Index: modules/project/comment.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/project/comment.inc,v retrieving revision 1.42 diff -u -r1.42 comment.inc --- modules/project/comment.inc 17 May 2005 06:21:20 -0000 1.42 +++ modules/project/comment.inc 26 May 2005 06:44:46 -0000 @@ -7,7 +7,7 @@ if (user_access('create project issues')) { $node = node_load(array('nid' => arg(3), 'type' => 'project_issue')); - foreach (array('nid', 'type', 'pid', 'rid', 'category', 'component', 'priority', 'assigned', 'state', 'title') as $var) { + foreach (array('nid', 'type', 'pid', 'rid', 'category', 'component', 'priority', 'assigned', 'sid', 'title') as $var) { $comment->$var = $node->$var; } @@ -103,7 +103,7 @@ 'category' => 'Category', 'priority' => 'Priority', 'assigned' => 'Assigned to', - 'state' => 'Status' + 'sid' => 'Status' ); $result = db_query('SELECT p.*, u.name FROM {project_comments} p INNER JOIN {users} u USING (uid) WHERE p.nid = %d ORDER BY p.created ASC', $node->nid); @@ -168,7 +168,7 @@ $node = node_load(array('nid' => $edit->nid, 'type' => 'project_issue')); // Check if comment changed any of the state values and update the node if necessary - foreach (array('pid', 'rid', 'category', 'component', 'priority', 'assigned', 'state', 'title') as $var) { + foreach (array('pid', 'rid', 'category', 'component', 'priority', 'assigned', 'sid', 'title') as $var) { if ($node->$var != $edit->$var) { $data['old']->$var = $node->$var; $data['new']->$var = $edit->$var; Index: modules/project/issue.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/project/issue.inc,v retrieving revision 1.102 diff -u -r1.102 issue.inc --- modules/project/issue.inc 17 May 2005 06:21:20 -0000 1.102 +++ modules/project/issue.inc 26 May 2005 06:33:09 -0000 @@ -5,6 +5,16 @@ return t('issue'); } +function project_issue_nodeapi(&$node, $op, $arg) { + switch ($op) { + case 'validate': + if (!user_access("set issue status '" . $node->sid . "'")) { + form_set_error('sid', t('Invalid issue status %status: you do not have permission to set this status', array('%status' => "$node->sid"))); + } + break; + } +} + function project_issue_page() { switch ($_POST['op'] ? $_POST['op'] : arg(2)) { case 'search': @@ -95,14 +105,14 @@ $header = array(t('Category'), t('Overall'), t('Last month')); $rows = array(); $duration = time() - 30 * 24 * 60 * 60; - $result = db_query('SELECT p.category, SUM(n.changed - n.created) / COUNT(p.category) AS duration FROM {project_issues} p INNER JOIN {node} n ON n.nid = p.nid WHERE n.status = 1%s AND p.state > 1 GROUP BY p.category', $filter); + $result = db_query('SELECT p.category, SUM(n.changed - n.created) / COUNT(p.category) AS duration FROM {project_issues} p INNER JOIN {node} n ON n.nid = p.nid WHERE n.status = 1%s AND p.sid > 1 GROUP BY p.category', $filter); while ($stat = db_fetch_object($result)) { $i++; $rows[$i][0] = project_issue_category($stat->category);; $rows[$i][1] = array('data' => format_interval($stat->duration, 2), 'class' => 'numeric'); } - $result = db_query('SELECT p.category, SUM(n.changed - n.created) / COUNT(p.category) AS duration FROM {project_issues} p INNER JOIN {node} n ON n.nid = p.nid WHERE n.status = 1%s AND p.state > 1 AND n.created > %d GROUP BY p.category', $filter, $duration); + $result = db_query('SELECT p.category, SUM(n.changed - n.created) / COUNT(p.category) AS duration FROM {project_issues} p INNER JOIN {node} n ON n.nid = p.nid WHERE n.status = 1%s AND p.sid > 1 AND n.created > %d GROUP BY p.category', $filter, $duration); while ($stat = db_fetch_object($result)) { $j++; $rows[$j][2] = array('data' => format_interval($stat->duration, 2), 'class' => 'numeric'); @@ -114,16 +124,16 @@ $rows = array(); // Activity overall $total = db_result(db_query(db_rewrite_sql('SELECT COUNT(n.nid) AS total FROM {project_issues} p INNER JOIN {node} n ON n.nid = p.nid WHERE n.status = 1%s'), $filter)); - $result = db_query(db_rewrite_sql('SELECT COUNT(n.nid) AS total, p.state FROM {project_issues} p INNER JOIN {node} n ON n.nid = p.nid WHERE n.status = 1%s GROUP BY p.state'), $filter); + $result = db_query(db_rewrite_sql('SELECT COUNT(n.nid) AS total, p.sid FROM {project_issues} p INNER JOIN {node} n ON n.nid = p.nid WHERE n.status = 1%s GROUP BY p.sid'), $filter); while ($stat = db_fetch_object($result)) { - $rows[$stat->state][0] = project_issue_state($stat->state);; - $rows[$stat->state][1] = array('data' => $stat->total, 'class' => 'project-numeric'); - $rows[$stat->state][2] = array('data' => number_format($stat->total / $total * 100) .'%', 'class' => 'project-numeric2'); + $rows[$stat->sid][0] = project_issue_state($stat->sid);; + $rows[$stat->sid][1] = array('data' => $stat->total, 'class' => 'project-numeric'); + $rows[$stat->sid][2] = array('data' => number_format($stat->total / $total * 100) .'%', 'class' => 'project-numeric2'); } // Activity this week - $result = db_query(db_rewrite_sql('SELECT COUNT(n.nid) AS total, p.state FROM {project_issues} p INNER JOIN {node} n ON n.nid = p.nid WHERE n.status = 1%s AND n.changed > %d GROUP BY p.state'), $filter, $duration); + $result = db_query(db_rewrite_sql('SELECT COUNT(n.nid) AS total, p.sid FROM {project_issues} p INNER JOIN {node} n ON n.nid = p.nid WHERE n.status = 1%s AND n.changed > %d GROUP BY p.sid'), $filter, $duration); while ($stat = db_fetch_object($result)) { - $rows[$stat->state][3] = array('data' => $stat->total, 'class' => 'project-numeric'); + $rows[$stat->sid][3] = array('data' => $stat->total, 'class' => 'project-numeric'); } $output .= '

'. t('Issue activity') .'

'; $output .= theme('table', $header, $rows); @@ -132,7 +142,7 @@ if (!$project->nid) { $header = array_merge(array(t('Project')), project_issue_state(), array(t('Total'))); $rows = array(); - $result = db_query(db_rewrite_sql("SELECT n.nid, n.title, p.state, COUNT(p.nid) AS total FROM {node} n INNER JOIN {project_issues} p ON n.nid = p.pid WHERE n.type = 'project_project' AND n.status = 1 GROUP BY n.nid, p.state, n.title")); + $result = db_query(db_rewrite_sql("SELECT n.nid, n.title, p.sid, COUNT(p.nid) AS total FROM {node} n INNER JOIN {project_issues} p ON n.nid = p.pid WHERE n.type = 'project_project' AND n.status = 1 GROUP BY n.nid, p.sid, n.title")); $orig = array('project' => array('data' => 0)); foreach (project_issue_state() as $key => $value) { @@ -146,7 +156,7 @@ $rows[$stat->nid]['project']['data'] = l($stat->title, "node/$stat->nid"); } $rows[$stat->nid]['total']['data'] += $stat->total; - $rows[$stat->nid][$stat->state]['data'] = $stat->total; + $rows[$stat->nid][$stat->sid]['data'] = $stat->total; } usort($rows, create_function('$a,$b', 'return $a[1]["data"] < $b[1]["data"];')); $output .= '

'. t('Project overview') .'

'; @@ -255,7 +265,7 @@ } $categories = array_merge(array(t('')), project_issue_category(0, 0)); $priorities = project_issue_priority(); - $states = project_issue_state(); + $states = project_issue_state(0, true); if ($user->uid == $node->assigned) { $assigned = array(0 => t('Unassign'), $user->uid => $user->name); @@ -276,7 +286,7 @@ $group2 = form_select(t('Category'), 'category', $node->category, $categories, NULL, 0, FALSE, TRUE); $group2 .= form_select(t('Priority'), 'priority', $node->priority, $priorities); $group2 .= form_select(t('Assigned'), 'assigned', $node->assigned, $assigned); - $group2 .= form_select(t('Status'), 'state', $node->state, $states); + $group2 .= form_select(t('Status'), 'sid', $node->sid, $states); $output .= ''; $output .= '
'; @@ -325,7 +335,7 @@ } empty($node->priority) and $node->priority = 2; empty($node->category) and $node->category = arg(4); - empty($node->state) and $node->state = 1; + empty($node->sid) and $node->sid = 1; if (isset($node->title)) { empty($node->component) and form_set_error($error['component'], t('You have to specify a valid component.')); @@ -369,7 +379,7 @@ $rows[] = array(t('Category:'), check_plain($node->category)); $rows[] = array(t('Priority:'), project_issue_priority($node->priority)); $rows[] = array(t('Assigned:'), $assigned); - $rows[] = array(t('Status:'), project_issue_state($node->state)); + $rows[] = array(t('Status:'), project_issue_state($node->sid)); if ($node->file_path && file_exists($node->file_path)) { $rows[] = array(t('Attachment:'), ''. basename($node->file_path) .' ('. format_size($node->file_size) .')'); } @@ -405,7 +415,7 @@ $file = file_save_upload($node->file, variable_get('project_directory_issues', 'issues')); } - db_query("INSERT INTO {project_issues} (nid, pid, category, component, priority, rid, assigned, state, file_path, file_mime, file_size) VALUES (%d, %d, '%s', '%s', %d, %d, %d, %d, '%s', '%s', %d)", $node->nid, $node->pid, $node->category, $node->component, $node->priority, $node->rid, $node->assigned, $node->state, $file->filepath, $file->filemime, $file->filesize); + db_query("INSERT INTO {project_issues} (nid, pid, category, component, priority, rid, assigned, sid, file_path, file_mime, file_size) VALUES (%d, %d, '%s', '%s', %d, %d, %d, %d, '%s', '%s', %d)", $node->nid, $node->pid, $node->category, $node->component, $node->priority, $node->rid, $node->assigned, $node->sid, $file->filepath, $file->filemime, $file->filesize); project_mail_notify($node); } @@ -414,10 +424,10 @@ // Remove old file. file_delete(db_result(db_query('SELECT file_path FROM {project_issues} WHERE nid = %d', $node->nid))); $file = file_save_upload($node->file, variable_get('project_directory_issues', 'issues')); - db_query("UPDATE {project_issues} SET pid = %d, category = '%s', component = '%s', priority = %d, rid = %d, assigned = %d, state = %d, file_path = '%s', file_mime = '%s', file_size = %d WHERE nid = %d", $node->pid, $node->category, $node->component, $node->priority, $node->rid, $node->assigned, $node->state, $file->filepath, $file->filemime, $file->filesize, $node->nid); + db_query("UPDATE {project_issues} SET pid = %d, category = '%s', component = '%s', priority = %d, rid = %d, assigned = %d, sid = %d, file_path = '%s', file_mime = '%s', file_size = %d WHERE nid = %d", $node->pid, $node->category, $node->component, $node->priority, $node->rid, $node->assigned, $node->sid, $file->filepath, $file->filemime, $file->filesize, $node->nid); } else { - db_query("UPDATE {project_issues} SET pid = %d, category = '%s', component = '%s', priority = %d, rid = %d, assigned = %d, state = %d WHERE nid = %d", $node->pid, $node->category, $node->component, $node->priority, $node->rid, $node->assigned, $node->state, $node->nid); + db_query("UPDATE {project_issues} SET pid = %d, category = '%s', component = '%s', priority = %d, rid = %d, assigned = %d, sid = %d WHERE nid = %d", $node->pid, $node->category, $node->component, $node->priority, $node->rid, $node->assigned, $node->sid, $node->nid); } project_mail_notify($node); } @@ -440,9 +450,28 @@ } // Support stuff -function project_issue_state($state = 0) { - $states = array(1 => t('active'), 2 => t('fixed'), 8=> t('patch'), 3 => t('duplicate'), 4 => t('postponed'), 5 => t("won't fix"), 6 => t('by design'), 7 => t('closed')); - return $state ? $states[$state] : $states; +function project_issue_state($sid = 0, $restrict = false) { + static $options; + + if (!$options) { + $result = db_query('SELECT * FROM {project_issue_state} ORDER BY weight'); + while ($stat = db_fetch_object($result)) { + $options[$stat->sid] = $stat->name; + } + } + + if($restrict) { + foreach($options as $key => $value) { + if (user_access("set issue status '" . $value . "'")) { + $states[$key] = $value; + } + } + } + else { + $states = $options; + } + + return $sid ? $states[$sid] : $states; } function project_issue_priority($priority = 0) { @@ -462,9 +491,9 @@ function project_issue_count($pid) { $state = array(); - $result = db_query('SELECT p.state, count(p.state) AS count FROM {node} n INNER JOIN {project_issues} p ON n.nid = p.nid WHERE n.status = 1 AND p.pid = %d GROUP BY p.state', $pid); + $result = db_query('SELECT p.sid, count(p.sid) AS count FROM {node} n INNER JOIN {project_issues} p ON n.nid = p.nid WHERE n.status = 1 AND p.pid = %d GROUP BY p.sid', $pid); while ($data = db_fetch_object($result)) { - $state[$data->state] = $data->count; + $state[$data->sid] = $data->count; } return $state; } @@ -529,6 +558,111 @@ return $output; } +function project_issue_admin_states() { + $result = db_query('SELECT * FROM {project_issue_state} ORDER BY weight'); + + while ($state = db_fetch_object($result)) { + $rows[] = array($state->sid, form_textfield(NULL, 'status][' . $state->sid .'][name', $state->name, 64, 255), form_weight(NULL, 'status][' . $state->sid .'][weight', $state->weight, 15), l(t('delete'), 'project/issues/status_settings/delete/'. $state->sid)); + } + for ($i = 0; $i < 3; $i++) { + $rows[] = array(NULL, form_textfield(NULL, 'status_add][' . $i . '][name', '', 64, 255), form_weight(NULL, 'status_add][' . $i .'][weight', 0, 15), NULL); + } + return $rows; +} + +function project_issue_admin_states_page() { + switch ($_POST['edit']['op'] ? $_POST['edit']['op'] : arg(3)) { + case 'save': + project_issue_admin_save_states(); + break; + case 'delete': + project_issue_admin_delete_state(); + break; + default: + $header = array( + array('data' => t('ID')), + array('data' => t('Name')), + array('data' => t('Weight'), 'colspan' => 2) + ); + + $output = '
' . theme('table', $header, project_issue_admin_states()) . '
'; + $output .= form_hidden('op', 'save'); + $output .= form_submit(t('Save issue settings')); + + $output = form($output); + + $output .= l('Project settings', 'admin/settings/project'); + print theme('page', $output); + break; + } +} + +function project_issue_admin_save_states() { + // Check for and apply changes or additions to project issue status options. + $edit = $_POST['edit']; + // Update existing status options. + if($edit['status']) { + foreach ($edit['status'] as $sid => $value) { + $state = db_fetch_object(db_query('SELECT name, weight FROM {project_issue_state} WHERE sid = %d', $sid)); + // Check to see whether the name needs updating: + if ($state->name != $value['name']) { + db_query("UPDATE {project_issue_state} SET name = '%s' WHERE sid = %d", $value['name'], $sid); + } + + // Check to see whether the weight needs updating: + if ($state->weight != $value['weight']) { + db_query('UPDATE {project_issue_state} SET weight = %d WHERE sid = %d', $value['weight'], $sid); + } + } + } + // Add any new status options. + if($edit['status_add']) { + foreach ($edit['status_add'] as $i => $value) { + if($value['name']) { + // Check to see whether the state already exists: + $name = db_result(db_query("SELECT name FROM {project_issue_state} WHERE name = '%s'", $value['name'])); + if (!db_num_rows($name)) { + db_query("INSERT INTO {project_issue_state} SET name = '%s', weight = %d", $value['name'], $value['weight']); + } + } + } + } + drupal_goto('project/issues/status_settings'); +} + +function project_issue_admin_delete_state() { + $sid = arg(4); + $edit = $_POST['edit']; + if (!$sid) { + $sid = $edit['sid']; + } + $states = project_issue_state(); + $name = $states[$sid]; + if ($edit['confirm'] && ($edit['new_sid'] != $sid)) { + if ($edit['new_sid']) { + db_query('UPDATE {project_issues} SET sid = %d WHERE sid = %d', $edit['new_sid'], $sid); + } + db_query('DELETE FROM {project_issue_state} WHERE sid = %d', $sid); + drupal_set_message(t('Project issue status %issue deleted.', array('%issue' => $name))); + drupal_goto('project/issues/status_settings'); + } + else { + if($edit['new_sid'] == $sid) { + form_set_error('new_sid', t('Choose a new issue status for existing issues of status %name.', array('%name' => $name))); + } + $total = db_result(db_query(db_rewrite_sql('SELECT COUNT(nid) AS total FROM {project_issues} WHERE sid = %d'), $sid)); + if ($total > 0) { + $output .= form_select(t('Reassign status'), 'new_sid', $sid, $states, t('There are %total existing issues with the status of %name. Please select a new status for these issues.', array('%total' => $total, '%name' => $name))); + } + $output .= form_item(t('Confirm deletion'), $name); + $output .= form_hidden('sid', $sid); + $output .= form_hidden('confirm', 1); + $output .= form_submit(t('Delete')); + $output = form($output); + print theme('page', $output); + } +} + function project_issue_query_result($query = NULL, $format = 'html', $search = true) { $query = project_issue_query_parse($query); @@ -569,7 +703,7 @@ $header[] = array('data' => t('Project'), 'field' => 'p.pid'); } $header[] = array('data' => t('Summary'), 'field' => 'n.title'); - $header[] = array('data' => t('Status'), 'field' => 'p.state'); + $header[] = array('data' => t('Status'), 'field' => 'p.sid'); $header[] = array('data' => t('Pri'), 'field' => 'p.priority'); $header[] = array('data' => t('Category'), 'field' => 'p.category'); if (count($releases)) { @@ -584,7 +718,7 @@ $result = pager_query(db_rewrite_sql($sql['sql'] . tablesort_sql($header)), 20, 0, $sql['count']); } else { - $result = pager_query(db_rewrite_sql('SELECT p.nid FROM {project_issues} p INNER JOIN {node} n ON n.nid = p.nid INNER JOIN {users} u ON p.assigned = u.uid INNER JOIN {node} np ON np.nid = p.pid WHERE n.status = 1 AND ('. implode(' OR ', $pids) .') AND (p.state = 1 OR p.state = 2)'. tablesort_sql($header), 'p'), 20); + $result = pager_query(db_rewrite_sql('SELECT p.nid FROM {project_issues} p INNER JOIN {node} n ON n.nid = p.nid INNER JOIN {users} u ON p.assigned = u.uid INNER JOIN {node} np ON np.nid = p.pid WHERE n.status = 1 AND ('. implode(' OR ', $pids) .') AND (p.sid = 1 OR p.sid = 2)'. tablesort_sql($header), 'p'), 20); } if ($search) { @@ -627,12 +761,12 @@ $node = node_load($node); $row = array(); $number++; - $class = 'state_'. ($number % 2 ? 'light' : 'dark') ."_$node->state"; + $class = 'state_'. ($number % 2 ? 'light' : 'dark') ."_$node->sid"; if (!$project->nid) { $row[] = l($projects[$node->pid], "project/issues/$node->pid"); } $row[] = l(substr($node->title, 0, 50), "node/$node->nid") . theme('mark', node_mark($node->nid, $node->changed)); - $row[] = $states[$node->state]; + $row[] = $states[$node->sid]; $row[] = $priorities[$node->priority]; $row[] = t($node->category); if (count($releases)) { @@ -764,7 +898,7 @@ $sql[] = project_issue_query_sql_field('p.rid', $value); break; case 'states': - $sql[] = project_issue_query_sql_field('p.state', $value); + $sql[] = project_issue_query_sql_field('p.sid', $value); break; case 'priorities': $sql[] = project_issue_query_sql_field('p.priority', $value); Index: modules/project/mail.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/project/mail.inc,v retrieving revision 1.48 diff -u -r1.48 mail.inc --- modules/project/mail.inc 26 May 2005 01:56:21 -0000 1.48 +++ modules/project/mail.inc 26 May 2005 06:46:42 -0000 @@ -22,7 +22,7 @@ 'priority' => t('Priority'), 'rid' => t('Version'), 'assigned' => t('Assigned to'), - 'state' => t('Status') + 'sid' => t('Status') ); /* @@ -68,9 +68,9 @@ $entry->assigned = $user->uid; } break; - case 'state': + case 'sid': if (($state = array_search($node->$text, project_issue_state()))) { - $entry->state = $state; + $entry->sid = $state; } break; case 'component': @@ -85,7 +85,7 @@ } if (empty($entry->nid)) { - $entry->state = 1; + $entry->sid = 1; $entry->type = 'project_issue'; $entry = node_validate($entry, $error); $error or ($entry->nid = node_save($entry)); @@ -179,7 +179,7 @@ case 'assigned': $user = user_load(array('uid' => $value)); return $user->name; - case 'state': + case 'sid': return $value ? project_issue_state($value) : t(''); default: return $value; @@ -202,7 +202,7 @@ 'assigned' => t('Assigned to'), 'name' => t('Reported by'), 'updator' => t('Updated by'), - 'state' => t('Status') + 'sid' => t('Status') ); // Create complete history of the bug report @@ -323,7 +323,7 @@ return; } - if (count($project->mail_copy_filter_state) && !$project->mail_copy_filter_state[$node->state]) { + if (count($project->mail_copy_filter_state) && !$project->mail_copy_filter_state[$node->sid]) { return; } @@ -344,7 +344,7 @@ $sender->name = variable_get('site_name', ''); $sender->mail = variable_get('site_mail', ''); - $result = db_query(db_rewrite_sql('SELECT p.nid, n.*, p.*, u.name, u.mail FROM {project_issues} p INNER JOIN {node} n ON p.nid = n.nid INNER JOIN {users} u ON n.uid = u.uid WHERE n.status = 1 AND u.status = 1 AND ('. implode(' OR ', $pids) .") AND u.mail <> '' AND (p.state = 1 OR p.state = 2) ORDER BY u.uid, p.pid, p.component, p.state, n.changed DESC", 'p')); + $result = db_query(db_rewrite_sql('SELECT p.nid, n.*, p.*, u.name, u.mail FROM {project_issues} p INNER JOIN {node} n ON p.nid = n.nid INNER JOIN {users} u ON n.uid = u.uid WHERE n.status = 1 AND u.status = 1 AND ('. implode(' OR ', $pids) .") AND u.mail <> '' AND (p.sid = 1 OR p.sid = 2) ORDER BY u.uid, p.pid, p.component, p.sid, n.changed DESC", 'p')); while (($node = db_fetch_object($result)) || !empty($body)) { if ($body && $mail && ((!$node) || ($mail != $node->mail))) { @@ -374,7 +374,7 @@ if ($node->assigned && $assigned = user_load(array('uid' => $node->assigned))) { $body .= " assigned: $assigned->name\n"; } - $body .= ' state: '. project_issue_state($node->state) ."\n"; + $body .= ' state: '. project_issue_state($node->sid) ."\n"; $body .= ' age: '. format_interval(time() - $node->created) ."\n"; $body .= ' url: '. url("node/$node->nid", NULL, NULL, 1) ."\n"; $body .= "\n"; @@ -395,7 +395,7 @@ $result = db_query(db_rewrite_sql("SELECT p.nid, p.* FROM {project_projects} p INNER JOIN {node} n ON n.nid = p.nid WHERE n.status = 1 AND p.mail_digest <> '' ORDER BY title, p.mail_digest", 'p')); while ($project = db_fetch_object($result)) { $category = ''; - $result2 = db_query(db_rewrite_sql('SELECT p.nid, n.title, n.created, p.state, p.category, p.component, p.priority, p.assigned FROM {project_issues} p INNER JOIN {node} n ON p.nid = n.nid WHERE n.status = 1 AND p.pid = %d AND p.state = 1 AND p.priority = 1 ORDER BY p.category, n.created DESC', 'p'), $project->nid); + $result2 = db_query(db_rewrite_sql('SELECT p.nid, n.title, n.created, p.sid, p.category, p.component, p.priority, p.assigned FROM {project_issues} p INNER JOIN {node} n ON p.nid = n.nid WHERE n.status = 1 AND p.pid = %d AND p.sid = 1 AND p.priority = 1 ORDER BY p.category, n.created DESC', 'p'), $project->nid); while ($node = db_fetch_object($result2)) { if ($category != $node->category) { $category = $node->category; Index: modules/project/project.module =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/project/project.module,v retrieving revision 1.195 diff -u -r1.195 project.module --- modules/project/project.module 24 May 2005 20:38:45 -0000 1.195 +++ modules/project/project.module 26 May 2005 07:09:27 -0000 @@ -40,6 +40,13 @@ return t('Add a new issue (bug report, feature request, etc) to an existing project.'); case 'node/add/project_project': return variable_get('project_help_node_add', ''); + case 'project/issues/status_settings': + return t('

Use this page to add new status options for project issues or to change or delete existing options.

+
Adding
To add a new status option, put its name in one of the blank places at the bottom of the form and assign it a weight.

+
Updating
When renaming existing issues, keep in mind that issues with the existing name will receive the new one.
+
Deleting
If you delete an existing issue status, you will be prompted for a new status to assign to existing issues with the deleted status.
+
Weights
The weight of an issue determines the order it appears in lists, like in the select box where users designate a status for their issue.
+

'); } } @@ -52,7 +59,7 @@ } function project_perm() { - return array( + $perms = array( 'administer projects', 'maintain projects', 'access projects', @@ -61,9 +68,15 @@ 'access project issues', 'access own project issues' ); + $states = project_issue_state(); + foreach($states as $key => $value) { + $perms[] = "set issue status '" . $value . "'"; + } + return $perms; } function project_settings() { + if (!file_check_directory(file_create_path(variable_get('project_directory_issues', 'issues')))) { $error['project_directory_issues'] = theme('error', t('Directory does not exist, or is not writable.')); } @@ -87,6 +100,8 @@ $output .= form_select(t('Reply-to address on e-mail notifications'), 'project_reply_to', variable_get('project_reply_to', ''), $items); } + $output .= '
' . l('Administer project issue status settings', 'project/issues/status_settings') . '
'; + return $output; } @@ -106,9 +121,9 @@ project_mail_reminder(); } - $result = db_query(db_rewrite_sql('SELECT p.nid, p.pid, p.category, p.component, p.priority, p.assigned, p.state, n.title FROM {project_issues} p INNER JOIN {node} n ON n.nid = p.nid WHERE n.status = 1 AND p.state = 2 AND n.changed < %d', 'p'), time() - 14 * 24 * 60 * 60); + $result = db_query(db_rewrite_sql('SELECT p.nid, p.pid, p.category, p.component, p.priority, p.assigned, p.sid, n.title FROM {project_issues} p INNER JOIN {node} n ON n.nid = p.nid WHERE n.status = 1 AND p.sid = 2 AND n.changed < %d', 'p'), time() - 14 * 24 * 60 * 60); while ($node = db_fetch_object($result)) { - foreach (array('nid', 'pid', 'category', 'component', 'priority', 'assigned', 'state', 'title') as $var) { + foreach (array('nid', 'pid', 'category', 'component', 'priority', 'assigned', 'sid', 'title') as $var) { $comment->$var = $node->$var; } $comment->state = 7; @@ -209,7 +224,14 @@ $access = user_access('create project issues'); $items[] = array('path' => 'node/add/project_issue', 'title' => t('issue'), 'callback' => 'node_page', 'access' => $access, 'type' => MENU_NORMAL_ITEM, 'weight' => 1); + // Administer issue status settings + $access = user_access('administer projects'); + $items[] = array('path' => 'project/issues/status_settings', 'title' => t('status options'), 'callback' => 'project_issue_admin_states_page', 'access' => $access, 'type' => MENU_NORMAL_ITEM); + $items[] = array('path' => 'project/issues/status_settings/save', 'title' => t('save'), 'callback' => 'project_issue_admin_states_page', 'access' => $access, 'type' => MENU_CALLBACK); + $items[] = array('path' => 'project/issues/status_settings/delete', 'title' => t('delete'), 'callback' => 'project_issue_admin_states_page', 'access' => $access, 'type' => MENU_CALLBACK); + // Comments + $access = user_access('create project issues'); $items[] = array('path' => 'project/comments', 'title' => t('comments'), 'callback' => 'project_comment_page', 'access' => $access, 'type' => MENU_CALLBACK); // Releases @@ -386,7 +408,7 @@ array('data' => t('Issues'), 'colspan' => 4, 'field' => 'count') ); - $result = db_query(db_rewrite_sql("SELECT n.nid, n.title, n.changed, COUNT(p.nid) AS count FROM {node} n LEFT JOIN {project_issues} p ON n.nid = p.pid AND p.state IN (1,2,8) WHERE n.type = 'project_project' AND n.status = 1 AND n.uid = %d GROUP BY n.nid, n.title, n.changed %s"), $user->uid, tablesort_sql($header)); + $result = db_query(db_rewrite_sql("SELECT n.nid, n.title, n.changed, COUNT(p.nid) AS count FROM {node} n LEFT JOIN {project_issues} p ON n.nid = p.pid AND p.sid IN (1,2,8) WHERE n.type = 'project_project' AND n.status = 1 AND n.uid = %d GROUP BY n.nid, n.title, n.changed %s"), $user->uid, tablesort_sql($header)); if (!db_num_rows($result)) { return ($current_user ? t('You have no projects.') : t('This user has no projects.')); Index: modules/project/project.mysql =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/project/project.mysql,v retrieving revision 1.14 diff -u -r1.14 project.mysql --- modules/project/project.mysql 25 May 2004 19:42:39 -0000 1.14 +++ modules/project/project.mysql 26 May 2005 06:40:48 -0000 @@ -70,6 +70,7 @@ ALTER TABLE project_issues ADD file_path varchar(255) NOT NULL default ''; ALTER TABLE project_issues ADD file_mime varchar(255) NOT NULL default ''; ALTER TABLE project_issues ADD file_size int NOT NULL default 0; +ALTER TABLE project_issues CHANGE state sid int(10) unsigned NOT NULL default '0'; -- -- Table structure for table 'project_comments' @@ -104,3 +105,31 @@ level tinyint(3) unsigned NOT NULL default '0', KEY project_subscriptions_nid_uid_level (nid, uid, level) ) TYPE=MyISAM; + +-- +-- Table structure for table 'project_issue_state' +-- + +CREATE TABLE project_issue_state ( + sid int(10) unsigned NOT NULL auto_increment, + name varchar(32) NOT NULL default '', + weight tinyint(2) DEFAULT '0' NOT NULL, + PRIMARY KEY (sid) +) TYPE=MyISAM; + +-- +-- Data for table 'project_issue_state' +-- + +INSERT INTO project_issue_state VALUES (1, 'active', -13); +INSERT INTO project_issue_state VALUES (2, 'applied', 1); +INSERT INTO project_issue_state VALUES (3, 'duplicate', 4); +INSERT INTO project_issue_state VALUES (4, 'postponed', 6); +INSERT INTO project_issue_state VALUES (5, 'won\'t fix', 9); +INSERT INTO project_issue_state VALUES (6, 'by design', 11); +INSERT INTO project_issue_state VALUES (7, 'closed', 13); +INSERT INTO project_issue_state VALUES (8, 'patch', -8); +INSERT INTO project_issue_state VALUES (9, 'needs work', -11); +INSERT INTO project_issue_state VALUES (10, 'testers needed', -6); +INSERT INTO project_issue_state VALUES (11, 'reviewed', -3); +INSERT INTO project_issue_state VALUES (12, 'ready to commit', -1); Index: modules/project/project.pgsql =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/project/project.pgsql,v retrieving revision 1.1 diff -u -r1.1 project.pgsql --- modules/project/project.pgsql 8 May 2005 13:47:56 -0000 1.1 +++ modules/project/project.pgsql 26 May 2005 07:13:48 -0000 @@ -59,7 +59,7 @@ priority smallint NOT NULL default '0', rid int NOT NULL default '0', assigned int NOT NULL default '0', - state smallint NOT NULL default '0', + sid int NOT NULL default '0', file_path varchar(255) NOT NULL default '', file_mime varchar(255) default '' NOT NULL, file_size int default 0 NOT NULL, @@ -102,3 +102,32 @@ CREATE SEQUENCE project_cid_seq INCREMENT 1 START 1; CREATE SEQUENCE project_rid_seq INCREMENT 1 START 1; + + +-- +-- Table structure for table 'project_issue_state' +-- + +CREATE TABLE project_issue_state ( + sid SERIAL, + name varchar(32) NOT NULL default '', + weight smallint DEFAULT '0' NOT NULL, + PRIMARY KEY (sid) +) TYPE=MyISAM; + +-- +-- Data for table 'project_issue_state' +-- + +INSERT INTO project_issue_state VALUES (1, 'active', -13); +INSERT INTO project_issue_state VALUES (2, 'applied', 1); +INSERT INTO project_issue_state VALUES (3, 'duplicate', 4); +INSERT INTO project_issue_state VALUES (4, 'postponed', 6); +INSERT INTO project_issue_state VALUES (5, 'won\'t fix', 9); +INSERT INTO project_issue_state VALUES (6, 'by design', 11); +INSERT INTO project_issue_state VALUES (7, 'closed', 13); +INSERT INTO project_issue_state VALUES (8, 'patch', -8); +INSERT INTO project_issue_state VALUES (9, 'needs work', -11); +INSERT INTO project_issue_state VALUES (10, 'testers needed', -6); +INSERT INTO project_issue_state VALUES (11, 'reviewed', -3); +INSERT INTO project_issue_state VALUES (12, 'ready to commit', -1);