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 10 Feb 2005 22:38:16 -0000 @@ -104,3 +104,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; + +-- +-- Dumping 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/issue.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/project/issue.inc,v retrieving revision 1.90 diff -u -r1.90 issue.inc --- modules/project/issue.inc 6 Feb 2005 12:32:41 -0000 1.90 +++ modules/project/issue.inc 10 Feb 2005 22:26:01 -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->state . "'")) { + form_set_error('state', t('Invalid issue status %status: you do not have permission to set this status', array('%status' => "$node->state"))); + } + break; + } +} + function project_issue_page() { switch ($_POST['op'] ? $_POST['op'] : arg(2)) { case 'search': @@ -225,7 +235,7 @@ } $categories = array_merge(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); @@ -410,8 +420,27 @@ } // 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')); +function project_issue_state($state = 0, $restrict = false) { + static $options; + + if (!$options) { + $result = db_query('SELECT * FROM {project_issue_state} ORDER BY weight'); + while ($state = db_fetch_object($result)) { + $options[$state->sid] = $state->name; + } + } + + if($restrict) { + foreach($options as $key => $value) { + if (user_access("set issue status '" . $value . "'")) { + $states[$key] = $value; + } + } + } + else { + $states = $options; + } + return $state ? $states[$state] : $states; } @@ -494,6 +523,101 @@ $output .= ''; 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']) { + 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 { + $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) { Index: modules/project/project.module =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/project/project.module,v retrieving revision 1.181 diff -u -r1.181 project.module --- modules/project/project.module 6 Feb 2005 19:59:02 -0000 1.181 +++ modules/project/project.module 10 Feb 2005 22:21:51 -0000 @@ -52,16 +52,22 @@ } function project_perm() { - return array( + $perms = array( 'administer projects', 'maintain projects', 'access projects', 'create project issues', 'access 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.')); } @@ -84,6 +90,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; } @@ -184,7 +192,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