1<?php 2# MantisBT - A PHP based bugtracking system 3 4# MantisBT is free software: you can redistribute it and/or modify 5# it under the terms of the GNU General Public License as published by 6# the Free Software Foundation, either version 2 of the License, or 7# (at your option) any later version. 8# 9# MantisBT is distributed in the hope that it will be useful, 10# but WITHOUT ANY WARRANTY; without even the implied warranty of 11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12# GNU General Public License for more details. 13# 14# You should have received a copy of the GNU General Public License 15# along with MantisBT. If not, see <http://www.gnu.org/licenses/>. 16 17/** 18 * Manage configuration for workflow Config 19 * 20 * @package MantisBT 21 * @copyright Copyright 2000 - 2002 Kenzaburo Ito - kenito@300baud.org 22 * @copyright Copyright 2002 MantisBT Team - mantisbt-dev@lists.sourceforge.net 23 * @link http://www.mantisbt.org 24 * 25 * @uses core.php 26 * @uses access_api.php 27 * @uses authentication_api.php 28 * @uses config_api.php 29 * @uses constant_inc.php 30 * @uses current_user_api.php 31 * @uses form_api.php 32 * @uses gpc_api.php 33 * @uses helper_api.php 34 * @uses html_api.php 35 * @uses lang_api.php 36 * @uses print_api.php 37 */ 38 39require_once( 'core.php' ); 40require_api( 'access_api.php' ); 41require_api( 'authentication_api.php' ); 42require_api( 'config_api.php' ); 43require_api( 'constant_inc.php' ); 44require_api( 'current_user_api.php' ); 45require_api( 'form_api.php' ); 46require_api( 'gpc_api.php' ); 47require_api( 'helper_api.php' ); 48require_api( 'html_api.php' ); 49require_api( 'lang_api.php' ); 50require_api( 'print_api.php' ); 51 52form_security_validate( 'manage_config_workflow_set' ); 53 54auth_reauthenticate(); 55 56/** 57 * Retrieves the value of configuration option for the project's parent 58 * (ALL_PROJECTS level if project, or file-level if all projects) 59 * @param integer $p_project Project. 60 * @param string $p_option Configuration option to retrieve. 61 * @return mixed configuration option value 62 */ 63function config_get_parent( $p_project, $p_option ) { 64 if( $p_project == ALL_PROJECTS ) { 65 return config_get_global( $p_option ); 66 } else { 67 return config_get( $p_option, null, null, ALL_PROJECTS ); 68 } 69} 70 71/** 72 * Retrieves the access level needed to change the configuration option in the 73 * project's parent (ALL_PROJECTS level if project, or file-level if all projects) 74 * @param integer $p_project Project. 75 * @param string $p_option Configuration option to retrieve. 76 * @return integer access level 77 */ 78function config_get_access_parent( $p_project, $p_option ) { 79 if( $p_project == ALL_PROJECTS ) { 80 return config_get_global( 'admin_site_threshold' ); 81 } else { 82 return config_get_access( $p_option, null, ALL_PROJECTS ); 83 } 84} 85 86 87$t_can_change_level = min( config_get_access( 'status_enum_workflow' ), config_get_access( 'report_bug_threshold' ), config_get_access( 'set_status_threshold' ) 88 , config_get_access( 'bug_submit_status' ), config_get_access( 'bug_resolved_status_threshold' ), config_get_access( 'bug_reopen_status' ) ); 89access_ensure_project_level( $t_can_change_level ); 90 91$t_redirect_url = 'manage_config_workflow_page.php'; 92$t_project = helper_get_current_project(); 93$t_access = current_user_get_access_level(); 94 95layout_page_header( lang_get( 'manage_workflow_config' ), $t_redirect_url ); 96 97layout_page_begin( 'manage_overview_page.php' ); 98 99# process the changes to threshold values 100$t_valid_thresholds = array( 101 'bug_submit_status', 102 'bug_resolved_status_threshold', 103 'bug_reopen_status', 104); 105 106foreach( $t_valid_thresholds as $t_threshold ) { 107 $t_access_current = config_get_access( $t_threshold ); 108 if( $t_access >= $t_access_current ) { 109 $f_value = gpc_get( 'threshold_' . $t_threshold ); 110 $t_value_current = config_get( $t_threshold ); 111 $t_value_parent = config_get_parent( $t_project, $t_threshold ); 112 113 $f_access = gpc_get( 'access_' . $t_threshold ); 114 $t_access_parent = config_get_access_parent( $t_project, $t_threshold ); 115 116 if( $f_value == $t_value_parent && $f_access == $t_access_parent ) { 117 # If new value is equal to parent and access has not changed 118 config_delete( $t_threshold, ALL_USERS, $t_project ); 119 } else if( $f_value != $t_value_current || $f_access != $t_access_current ) { 120 # Set config if value or access have changed 121 config_set( $t_threshold, $f_value, NO_USER, $t_project, $f_access ); 122 } 123 } 124} 125 126$t_enum_status = MantisEnum::getAssocArrayIndexedByValues( config_get( 'status_enum_string' ) ); 127 128# process the workflow by reversing the flags to a matrix and creating the appropriate string 129if( config_get_access( 'status_enum_workflow' ) <= $t_access ) { 130 $f_value = gpc_get( 'flag', array() ); 131 $f_access = gpc_get( 'workflow_access' ); 132 $t_matrix = array(); 133 134 foreach( $f_value as $t_transition ) { 135 list( $t_from, $t_to ) = explode( ':', $t_transition ); 136 $t_matrix[$t_from][$t_to] = ''; 137 } 138 $t_workflow = array(); 139 foreach( $t_enum_status as $t_state => $t_label ) { 140 $t_workflow_row = ''; 141 $t_default = gpc_get_int( 'default_' . $t_state ); 142 if( isset( $t_matrix[$t_state] ) && isset( $t_matrix[$t_state][$t_default] ) ) { 143 $t_workflow_row .= $t_default . ':' . get_enum_element( 'status', $t_default ); 144 unset( $t_matrix[$t_state][$t_default] ); 145 $t_first = false; 146 } else { 147 # error default state isn't in the matrix 148 echo '<p>' . sprintf( lang_get( 'default_not_in_flow' ), get_enum_element( 'status', $t_default ), get_enum_element( 'status', $t_state ) ) . '</p>'; 149 $t_first = true; 150 } 151 if( isset( $t_matrix[$t_state] ) ) { 152 foreach ( $t_matrix[$t_state] as $t_next_state => $t_junk ) { 153 if( false == $t_first ) { 154 $t_workflow_row .= ','; 155 } 156 $t_workflow_row .= $t_next_state . ':' . get_enum_element( 'status', $t_next_state ); 157 $t_first = false; 158 } 159 } 160 # $t_workflow_row is allowed to be empty '' 161 $t_workflow[$t_state] = $t_workflow_row; 162 } 163 164 # Get the parent's workflow, if not set default to all transitions 165 $t_access_parent = config_get_access_parent( $t_project, 'status_enum_workflow' ); 166 $t_access_current = config_get_access( 'status_enum_workflow' ); 167 $t_workflow_parent = config_get_parent( $t_project, 'status_enum_workflow' ); 168 if( 0 == count( $t_workflow_parent ) ) { 169 foreach( $t_enum_status as $t_status => $t_label ) { 170 $t_temp_workflow = array(); 171 foreach( $t_enum_status as $t_next => $t_next_label ) { 172 if( $t_status != $t_next ) { 173 $t_temp_workflow[] = $t_next . ':' . $t_next_label; 174 } 175 } 176 $t_workflow_parent[$t_status] = implode( ',', $t_temp_workflow ); 177 } 178 } 179 180 if( $t_workflow == $t_workflow_parent && $f_access == $t_access_parent ) { 181 # If new value is equal to parent and access has not changed 182 config_delete( 'status_enum_workflow', ALL_USERS, $t_project ); 183 } else if( $t_workflow != config_get( 'status_enum_workflow' ) || $f_access != $t_access_current ) { 184 # Set config if value or access have changed 185 config_set( 'status_enum_workflow', $t_workflow, NO_USER, $t_project, $f_access ); 186 } 187} 188 189# process the access level changes 190if( min( config_get_access( 'set_status_threshold' ), config_get_access( 'report_bug_threshold' ) ) <= $t_access ) { 191 # get changes to access level to change these values 192 $f_access = gpc_get( 'status_access' ); 193 $t_access_parent = config_get_access_parent( $t_project, 'set_status_threshold' ); 194 $t_access_current = config_get_access( 'set_status_threshold' ); 195 196 # Build access level reference arrays (parent level and current config) 197 $t_set_parent = config_get_parent( $t_project, 'set_status_threshold' ); 198 $t_set_current = config_get( 'set_status_threshold' ); 199 $t_bug_submit_status = config_get( 'bug_submit_status' ); 200 foreach( $t_enum_status as $t_status => $t_status_label ) { 201 if( !isset( $t_set_parent[$t_status] ) ) { 202 if( $t_bug_submit_status == $t_status && config_get_access( 'report_bug_threshold' ) <= $t_access ) { 203 $t_set_parent[$t_status] = config_get_parent( $t_project, 'report_bug_threshold' ); 204 } elseif( config_get_access( 'set_status_threshold' ) <= $t_access ) { 205 $t_set_parent[$t_status] = config_get_parent( $t_project, 'update_bug_status_threshold' ); 206 } 207 } 208 if( !isset( $t_set_current[$t_status] ) ) { 209 if( $t_bug_submit_status == $t_status && config_get_access( 'report_bug_threshold' ) <= $t_access ) { 210 $t_set_current[$t_status] = config_get( 'report_bug_threshold' ); 211 } elseif( config_get_access( 'set_status_threshold' ) <= $t_access ) { 212 $t_set_current[$t_status] = config_get( 'update_bug_status_threshold' ); 213 } 214 } 215 } 216 217 # walk through the status labels to set the status threshold 218 $t_set_new = array(); 219 foreach( $t_enum_status as $t_status_id => $t_status_label ) { 220 $f_level = gpc_get_int( 'access_change_' . $t_status_id, -1 ); 221 if( config_get( 'bug_submit_status' ) == $t_status_id ) { 222 # Check if input exists 223 if( $f_level > -1 ) { 224 if( $f_level != $t_set_parent[$t_status_id] ) { 225 config_set( 'report_bug_threshold', (int)$f_level, ALL_USERS, $t_project, $f_access ); 226 } else { 227 config_delete( 'report_bug_threshold', ALL_USERS, $t_project ); 228 } 229 } 230 unset( $t_set_parent[$t_status_id] ); 231 unset( $t_set_current[$t_status_id] ); 232 } else { 233 # Only process those inputs that exist, since not all access_change_<status> may have been editable. 234 if( $f_level > -1 ) { 235 $t_set_new[$t_status_id] = $f_level; 236 } else { 237 if( isset( $t_set_current[$t_status_id] ) ) { 238 $t_set_new[$t_status_id] = $t_set_current[$t_status_id]; 239 } 240 } 241 } 242 } 243 244 if( $t_set_new == $t_set_parent && $f_access == $t_access_parent ) { 245 # If new value is equal to parent and access has not changed 246 config_delete( 'set_status_threshold', ALL_USERS, $t_project ); 247 } else if( $t_set_new != $t_set_current || $f_access != $t_access_current ) { 248 # Set config if value or access have changed 249 config_set( 'set_status_threshold', $t_set_new, ALL_USERS, $t_project, $f_access ); 250 } 251} 252 253form_security_purge( 'manage_config_workflow_set' ); 254 255html_operation_successful( $t_redirect_url ); 256 257layout_page_end(); 258