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 * Workflow Configuration Page 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 authentication_api.php 27 * @uses config_api.php 28 * @uses constant_inc.php 29 * @uses current_user_api.php 30 * @uses form_api.php 31 * @uses helper_api.php 32 * @uses html_api.php 33 * @uses lang_api.php 34 * @uses print_api.php 35 * @uses project_api.php 36 * @uses string_api.php 37 * @uses workflow_api.php 38 */ 39 40require_once( 'core.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( 'helper_api.php' ); 47require_api( 'html_api.php' ); 48require_api( 'lang_api.php' ); 49require_api( 'print_api.php' ); 50require_api( 'project_api.php' ); 51require_api( 'string_api.php' ); 52require_api( 'workflow_api.php' ); 53 54auth_reauthenticate(); 55 56layout_page_header( lang_get( 'manage_workflow_config' ) ); 57 58layout_page_begin( 'manage_overview_page.php' ); 59 60print_manage_menu( PAGE_CONFIG_DEFAULT ); 61print_manage_config_menu( 'manage_config_workflow_page.php' ); 62 63# CSS class names for overrides color coding 64define( 'COLOR_GLOBAL', 'color-global' ); 65define( 'COLOR_PROJECT', 'color-project' ); 66 67$g_access = current_user_get_access_level(); 68$t_project = helper_get_current_project(); 69$g_can_change_workflow = ( $g_access >= config_get_access( 'status_enum_workflow' ) ); 70$g_can_change_flags = $g_can_change_workflow; 71$g_overrides = array(); 72 73/** 74 * Set overrides 75 * @param string $p_config Configuration value. 76 * @param bool $p_can_change True if user has access level to change config 77 * @param string $p_color CSS class name 78 * @return void 79 */ 80function set_overrides( $p_config, $p_can_change, $p_color ) { 81 global $g_overrides; 82 83 if( !$p_can_change ) { 84 return; 85 } 86 87 $t_project = helper_get_current_project(); 88 if( $t_project == ALL_PROJECTS && $p_color == COLOR_GLOBAL 89 || $t_project != ALL_PROJECTS && $p_color == COLOR_PROJECT 90 ) { 91 $g_overrides[$p_config] = $p_config; 92 } 93} 94 95/** 96 * Returns a string to define the background color attribute depending 97 * on the level where it's overridden 98 * @param integer $p_level_file Config file's access level. 99 * @param integer $p_level_global All projects' access level. 100 * @param integer $p_level_project Current project's access level. 101 * @return string class name or '' if no override. 102 */ 103function set_color_override( $p_level_file, $p_level_global, $p_level_project ) { 104 if( $p_level_project != $p_level_global ) { 105 $t_color = COLOR_PROJECT; 106 } else if( $p_level_global != $p_level_file ) { 107 $t_color = COLOR_GLOBAL; 108 } else { 109 $t_color = ''; 110 } 111 112 return $t_color; 113} 114 115 116/** 117 * Get the value associated with the specific action and flag. 118 * @param integer $p_from_status_id From status id. 119 * @param integer $p_to_status_id To status id. 120 * @return string 121 */ 122function show_flag( $p_from_status_id, $p_to_status_id ) { 123 global $g_can_change_workflow, 124 $g_file_workflow, $g_global_workflow, $g_project_workflow, 125 $t_resolved_status, $t_reopen_status, $t_reopen_label; 126 if( $p_from_status_id <> $p_to_status_id ) { 127 $t_file = isset( $g_file_workflow['exit'][$p_from_status_id][$p_to_status_id] ) ? 1 : 0; 128 $t_global = isset( $g_global_workflow['exit'][$p_from_status_id][$p_to_status_id] ) ? 1 : 0; 129 $t_project = isset( $g_project_workflow['exit'][$p_from_status_id][$p_to_status_id] ) ? 1 : 0; 130 131 $t_color = set_color_override( $t_file, $t_global, $t_project ); 132 set_overrides( 'status_enum_workflow', $g_can_change_workflow, $t_color ); 133 $t_value = '<td class="center ' . $t_color . '">'; 134 135 $t_flag = ( 1 == $t_project ); 136 137 if( $g_can_change_workflow ) { 138 $t_flag_name = $p_from_status_id . ':' . $p_to_status_id; 139 $t_set = $t_flag ? 'checked="checked"' : ''; 140 $t_value .= '<label><input type="checkbox" class="ace" name="flag[]" value="' . $t_flag_name . '" ' . $t_set . ' /><span class="lbl"></span></label>'; 141 } else { 142 $t_value .= $t_flag ? icon_get( 'fa-check', 'fa-lg blue' ) : ' '; 143 } 144 145 # Add 'reopened' label 146 if( $p_from_status_id >= $t_resolved_status && $p_to_status_id == $t_reopen_status ) { 147 $t_value .= '<br /><small>(' . $t_reopen_label . ')</small>'; 148 } 149 } else { 150 $t_value = '<td> '; 151 } 152 153 $t_value .= '</td>'; 154 155 return $t_value; 156} 157 158/** 159 * section header 160 * @param string $p_section_name Section name. 161 * @return void 162 */ 163function section_begin( $p_section_name ) { 164 $t_enum_statuses = MantisEnum::getValues( config_get( 'status_enum_string' ) ); 165 echo '<div class="space-10"></div>'; 166 echo '<div class="widget-box widget-color-blue2">'; 167 echo ' <div class="widget-header widget-header-small">'; 168 echo ' <h4 class="widget-title lighter uppercase">'; 169 echo ' ' . icon_get( 'fa-random', 'ace-icon' ); 170 echo $p_section_name; 171 echo ' </h4>'; 172 echo ' </div>'; 173 echo ' <div class="widget-body">'; 174 echo ' <div class="widget-main no-padding">'; 175 echo ' <div class="table-responsive">'; 176 echo "\t<table class=\"table table-striped table-bordered table-condensed\">\n"; 177 echo "\t\t<thead>\n"; 178 echo "\t\t" . '<tr>' . "\n"; 179 echo "\t\t\t" . '<th class="bold" rowspan="2">' . lang_get( 'current_status' ) . '</th>'. "\n"; 180 echo "\t\t\t" . '<th class="bold" style="text-align:center" colspan="' . ( count( $t_enum_statuses ) + 1 ) . '">' 181 . lang_get( 'next_status' ) . '</th>'; 182 echo "\n\t\t" . '</tr>'. "\n"; 183 echo "\t\t" . '<tr>' . "\n"; 184 185 foreach( $t_enum_statuses as $t_status ) { 186 echo "\t\t\t" . '<th class="bold" style="text-align:center"> ' 187 . string_no_break( MantisEnum::getLabel( lang_get( 'status_enum_string' ), $t_status ) ) 188 . ' </th>' ."\n"; 189 } 190 191 echo "\t\t\t" . '<th class="bold" style="text-align:center">' . lang_get( 'custom_field_default_value' ) . '</th>' . "\n"; 192 echo "\t\t" . '</tr>' . "\n"; 193 echo "\t\t</thead>\n"; 194 echo "\t\t<tbody>\n"; 195} 196 197/** 198 * Print row 199 * @param integer $p_from_status From status. 200 * @return void 201 */ 202function capability_row( $p_from_status ) { 203 global $g_file_workflow, $g_global_workflow, $g_project_workflow, $g_can_change_workflow; 204 $t_enum_status = MantisEnum::getAssocArrayIndexedByValues( config_get( 'status_enum_string' ) ); 205 echo "\t\t" .'<tr><td>' . string_no_break( MantisEnum::getLabel( lang_get( 'status_enum_string' ), $p_from_status ) ) . '</td>' . "\n"; 206 foreach ( $t_enum_status as $t_to_status_id => $t_to_status_label ) { 207 echo show_flag( $p_from_status, $t_to_status_id ); 208 } 209 210 $t_file = isset( $g_file_workflow['default'][$p_from_status] ) ? $g_file_workflow['default'][$p_from_status] : 0 ; 211 $t_global = isset( $g_global_workflow['default'][$p_from_status] ) ? $g_global_workflow['default'][$p_from_status] : 0 ; 212 $t_project = isset( $g_project_workflow['default'][$p_from_status] ) ? $g_project_workflow['default'][$p_from_status] : 0; 213 214 $t_color = set_color_override( $t_file, $t_global, $t_project ); 215 set_overrides( 'status_enum_workflow', $g_can_change_workflow, $t_color ); 216 217 echo "\t\t\t" . '<td class="center ' . $t_color . '">'; 218 if( $g_can_change_workflow ) { 219 echo '<select name="default_' . $p_from_status . '" class="input-sm">'; 220 print_enum_string_option_list( 'status', $t_project ); 221 echo '</select>'; 222 } else { 223 echo MantisEnum::getLabel( lang_get( 'status_enum_string' ), $t_project ); 224 } 225 echo ' </td>' . "\n"; 226 echo "\t\t" . '</tr>' . "\n"; 227} 228 229/** 230 * section footer 231 * @return void 232 */ 233function section_end() { 234 global $g_can_change_workflow; 235 echo '</tbody></table></div>' . "\n"; 236 echo '</div></div></div>' . "\n"; 237 echo '<div class="space-10"></div>'; 238 239 if( $g_can_change_workflow ) { 240 echo lang_get( 'workflow_change_access_label' ) . " \n"; 241 echo '<select name="workflow_access">' . "\n"; 242 print_enum_string_option_list( 'access_levels', config_get_access( 'status_enum_workflow' ) ); 243 echo "\n" . '</select>' . "\n"; 244 } 245 246 echo '<div class="space-10"></div>'; 247} 248 249/** 250 * threshold section begin 251 * @param string $p_section_name Section name. 252 * @return void 253 */ 254function threshold_begin( $p_section_name ) { 255 echo '<div class="space-10"></div>'; 256 echo '<div class="widget-box widget-color-blue2">'; 257 echo ' <div class="widget-header widget-header-small">'; 258 echo ' <h4 class="widget-title lighter uppercase">'; 259 echo ' ' . icon_get( 'fa-sliders', 'ace-icon' ); 260 echo $p_section_name; 261 echo ' </h4>'; 262 echo ' </div>'; 263 echo ' <div class="widget-body">'; 264 echo ' <div class="widget-main no-padding">'; 265 echo ' <div class="table-responsive">'; 266 echo '<table class="table table-striped table-bordered table-condensed">'; 267 echo '<thead>'; 268 echo "\t" . '<tr>'; 269 echo "\t\t" . '<th class="bold">' . lang_get( 'threshold' ) . '</th>' . "\n"; 270 echo "\t\t" . '<th class="bold" >' . lang_get( 'status_level' ) . '</th>' . "\n"; 271 echo "\t\t" . '<th class="bold" >' . lang_get( 'alter_level' ) . '</th></tr>' . "\n"; 272 echo "\n"; 273 echo '</thead>'; 274 echo '<tbody>'; 275} 276 277/** 278 * threshold section row 279 * @param string $p_threshold Threshold. 280 * @return void 281 */ 282function threshold_row( $p_threshold ) { 283 global $g_access, $g_can_change_flags; 284 285 $t_can_change_threshold = ( $g_access >= config_get_access( $p_threshold ) ); 286 287 $t_file = config_get_global( $p_threshold ); 288 $t_global = config_get( $p_threshold, null, ALL_USERS, ALL_PROJECTS ); 289 $t_project = config_get( $p_threshold ); 290 $t_color = set_color_override( $t_file, $t_global, $t_project ); 291 set_overrides( $p_threshold, $t_can_change_threshold, $t_color ); 292 293 $t_file_access = config_get_global( 'admin_site_threshold' ); 294 $t_global_access = config_get_access( $p_threshold, ALL_USERS, ALL_PROJECTS); 295 $t_project_access = config_get_access( $p_threshold ); 296 $t_color_access = set_color_override( $t_file_access, $t_global_access, $t_project_access ); 297 set_overrides( $p_threshold, $t_can_change_threshold, $t_color_access ); 298 299 echo '<tr><td>' . lang_get( 'desc_' . $p_threshold ) . '</td>' . "\n"; 300 if( $t_can_change_threshold ) { 301 echo '<td class="' . $t_color . '"><select name="threshold_' . $p_threshold . '" class="input-sm">'; 302 print_enum_string_option_list( 'status', $t_project ); 303 echo '</select> </td>' . "\n"; 304 echo '<td class="' . $t_color_access . '"><select name="access_' . $p_threshold . '" class="input-sm">'; 305 print_enum_string_option_list( 'access_levels', config_get_access( $p_threshold ) ); 306 echo '</select> </td>' . "\n"; 307 $g_can_change_flags = true; 308 } else { 309 echo '<td class="' . $t_color . '">' . MantisEnum::getLabel( lang_get( 'status_enum_string' ), $t_project ) . ' </td>' . "\n"; 310 echo '<td>' . MantisEnum::getLabel( lang_get( 'access_levels_enum_string' ), config_get_access( $p_threshold ) ) . ' </td>' . "\n"; 311 } 312 313 echo '</tr>' . "\n"; 314} 315 316/** 317 * threshold section end 318 * @return void 319 */ 320function threshold_end() { 321 echo '</tbody></table></div>' . "\n"; 322 echo '</div></div></div>' . "\n"; 323 echo '<div class="space-10"></div>'; 324} 325 326/** 327 * access begin 328 * @param string $p_section_name Section name. 329 * @return void 330 */ 331function access_begin( $p_section_name ) { 332 echo '<div class="space-10"></div>'; 333 echo '<div class="widget-box widget-color-blue2">'; 334 echo ' <div class="widget-header widget-header-small">'; 335 echo ' <h4 class="widget-title lighter uppercase">'; 336 echo ' ' . icon_get( 'fa-lock', 'ace-icon' ); 337 echo $p_section_name; 338 echo ' </h4>'; 339 echo ' </div>'; 340 echo ' <div class="widget-body">'; 341 echo ' <div class="widget-main no-padding">'; 342 echo ' <div class="widget-toolbox padding-8 clearfix">'; 343 echo lang_get( 'access_change' ); 344 echo ' </div>'; 345 echo ' <div class="table-responsive">'; 346 echo ' <table class="table table-striped table-bordered table-condensed">'; 347 echo ' <tbody>'; 348} 349 350/** 351 * access row 352 * @return void 353 */ 354function access_row() { 355 global $g_access, $g_can_change_flags; 356 357 $t_enum_status = MantisEnum::getAssocArrayIndexedByValues( config_get( 'status_enum_string' ) ); 358 359 $t_file_new = config_get_global( 'report_bug_threshold' ); 360 $t_global_new = config_get( 'report_bug_threshold', null, ALL_USERS, ALL_PROJECTS ); 361 $t_report_bug_threshold = config_get( 'report_bug_threshold' ); 362 363 $t_file_set = config_get_global( 'set_status_threshold' ); 364 $t_global_set = config_get( 'set_status_threshold', null, ALL_USERS, ALL_PROJECTS ); 365 $t_project_set = config_get( 'set_status_threshold' ); 366 367 $t_submit_status = config_get( 'bug_submit_status' ); 368 369 # Print the table rows 370 foreach( $t_enum_status as $t_status => $t_status_label ) { 371 echo "\t\t" . '<tr><td>' 372 . string_no_break( MantisEnum::getLabel( lang_get( 'status_enum_string' ), $t_status ) ) . '</td>' . "\n"; 373 374 if( $t_status == $t_submit_status ) { 375 # 'NEW' status 376 $t_threshold = $t_report_bug_threshold; 377 378 $t_can_change = $g_access >= config_get_access( 'report_bug_threshold' ); 379 $t_color = set_color_override( $t_file_new, $t_global_new, $t_report_bug_threshold ); 380 set_overrides( 'report_bug_threshold', $t_can_change, $t_color ); 381 } else { 382 # Other statuses 383 384 # File level: fallback if set_status_threshold is not defined 385 if( isset( $t_file_set[$t_status] ) ) { 386 $t_level_file = $t_file_set[$t_status]; 387 } else { 388 $t_level_file = config_get_global( 'update_bug_status_threshold' ); 389 } 390 391 $t_level_global = isset( $t_global_set[$t_status] ) ? $t_global_set[$t_status] : $t_level_file; 392 $t_threshold = isset( $t_project_set[$t_status] ) ? $t_project_set[$t_status] : $t_level_global; 393 394 $t_can_change = ( $g_access >= config_get_access( 'set_status_threshold' ) ); 395 396 $t_color = set_color_override( $t_level_file, $t_level_global, $t_threshold ); 397 set_overrides( 'set_status_threshold', $t_can_change, $t_color ); 398 } 399 400 # If threshold is an array (instead of an integer value), the input is not editable 401 $t_can_edit = !is_array( $t_threshold ); 402 $t_min_level = access_threshold_min_level( $t_threshold ); 403 if( $t_can_change && $t_can_edit ) { 404 echo '<td class="' . $t_color . '"><select name="access_change_' . $t_status . '" class="input-sm">' . "\n"; 405 print_enum_string_option_list( 'access_levels', $t_min_level ); 406 echo '</select> </td>' . "\n"; 407 $g_can_change_flags = true; 408 } else { 409 echo '<td class="' . $t_color . '">' 410 . MantisEnum::getLabel( lang_get( 'access_levels_enum_string' ), $t_min_level ) 411 . '</td>' . "\n"; 412 } 413 414 echo '</tr>' . "\n"; 415 } 416} # end function access_row 417 418/** 419 * access section end 420 * @return void 421 */ 422function access_end() { 423 global $g_access; 424 425 echo '</tbody></table></div>' . "\n"; 426 echo '</div></div></div>' . "\n"; 427 echo '<div class="space-10"></div>'; 428 429 if( $g_access >= config_get_access( 'set_status_threshold' ) ) { 430 echo lang_get( 'access_change_access_label' ) . " \n"; 431 echo '<select name="status_access">' . "\n\t\t"; 432 print_enum_string_option_list( 'access_levels', config_get_access( 'set_status_threshold' ) ); 433 echo "\n" . '</select>' . "\n"; 434 } 435 436 echo '<div class="space-10"></div>'; 437} 438 439echo '<div class="space-10"></div>'; 440 441# count arcs in and out of each status 442$t_enum_status = config_get( 'status_enum_string' ); 443$t_status_arr = MantisEnum::getAssocArrayIndexedByValues( $t_enum_status ); 444 445$t_extra_enum_status = '0:non-existent,' . $t_enum_status; 446$t_lang_enum_status = '0:' . lang_get( 'non_existent' ) . ',' . lang_get( 'status_enum_string' ); 447$t_all_status = explode( ',', $t_extra_enum_status ); 448 449# gather all versions of the workflow 450$g_file_workflow = workflow_parse( config_get_global( 'status_enum_workflow' ) ); 451$g_global_workflow = workflow_parse( config_get( 'status_enum_workflow', null, ALL_USERS, ALL_PROJECTS ) ); 452$g_project_workflow = workflow_parse( config_get( 'status_enum_workflow', null, ALL_USERS, $t_project ) ); 453 454# validate the project workflow 455$t_validation_result = ''; 456foreach( $t_status_arr as $t_status => $t_label ) { 457 if( isset( $g_project_workflow['exit'][$t_status][$t_status] ) ) { 458 $t_validation_result .= '<tr><td>' 459 . MantisEnum::getLabel( $t_lang_enum_status, $t_status ) 460 . '</td><td class="alert alert-warning">' . lang_get( 'superfluous' ) . '</td></tr>'; 461 } 462} 463 464# check for entry == 0 without exit == 0, unreachable state 465foreach( $t_status_arr as $t_status => $t_status_label ) { 466 if( ( 0 == count( $g_project_workflow['entry'][$t_status] ) ) && ( 0 < count( $g_project_workflow['exit'][$t_status] ) ) ) { 467 $t_validation_result .= '<tr><td>' 468 . MantisEnum::getLabel( $t_lang_enum_status, $t_status ) 469 . '</td><td class="alert alert-danger">' . lang_get( 'unreachable' ) . '</td></tr>'; 470 } 471} 472 473# check for exit == 0 without entry == 0, unleaveable state 474foreach( $t_status_arr as $t_status => $t_status_label ) { 475 if( ( 0 == count( $g_project_workflow['exit'][$t_status] ) ) && ( 0 < count( $g_project_workflow['entry'][$t_status] ) ) ) { 476 $t_validation_result .= '<tr><td>' 477 . MantisEnum::getLabel( $t_lang_enum_status, $t_status ) 478 . '</td><td class="alert alert-danger">' . lang_get( 'no_exit' ) . '</td></tr>'; 479 } 480} 481 482# check for exit == 0 and entry == 0, isolated state 483foreach ( $t_status_arr as $t_status => $t_status_label ) { 484 if( ( 0 == count( $g_project_workflow['exit'][$t_status] ) ) && ( 0 == count( $g_project_workflow['entry'][$t_status] ) ) ) { 485 $t_validation_result .= '<tr><td>' 486 . MantisEnum::getLabel( $t_lang_enum_status, $t_status ) 487 . '</td><td class="alert alert-danger">' . lang_get( 'unreachable' ) . '<br />' . lang_get( 'no_exit' ) . '</td></tr>'; 488 } 489} 490 491echo '<form id="workflow_config_action" method="post" action="manage_config_workflow_set.php">' . "\n"; 492echo '<fieldset>'; 493echo form_security_field( 'manage_config_workflow_set' ); 494echo '</fieldset>'; 495 496if( ALL_PROJECTS == $t_project ) { 497 $t_project_title = lang_get( 'config_all_projects' ); 498} else { 499 $t_project_title = sprintf( lang_get( 'config_project' ), string_display_line( project_get_name( $t_project ) ) ); 500} 501 502echo '<div class="col-md-12 col-xs-12">' . "\n"; 503echo '<div class="well">' . "\n"; 504echo '<p class="bold">' . icon_get( 'fa-info-circle' ) . " $t_project_title</p>\n"; 505echo '<p>' . lang_get( 'colour_coding' ) . '<br />'; 506if( ALL_PROJECTS <> $t_project ) { 507 echo '<span class="' . COLOR_PROJECT . '">' . lang_get( 'colour_project' ) .'</span><br />'; 508} 509echo '<span class="' . COLOR_GLOBAL . '">' . lang_get( 'colour_global' ) . '</span></p>'; 510echo '</div>' . "\n"; 511 512# show the settings used to derive the table 513threshold_begin( lang_get( 'workflow_thresholds' ) ); 514if( !is_array( config_get( 'bug_submit_status' ) ) ) { 515 threshold_row( 'bug_submit_status' ); 516} 517threshold_row( 'bug_resolved_status_threshold' ); 518threshold_row( 'bug_reopen_status' ); 519threshold_end(); 520 521if( '' <> $t_validation_result ) { 522 echo '<div class="widget-box widget-color-blue2">'; 523 echo '<div class="widget-header widget-header-small">'; 524 echo ' <h4 class="widget-title lighter">'; 525 echo ' ' . icon_get( 'fa-hand-o-right', 'ace-icon' ); 526 echo lang_get( 'validation' ); 527 echo ' </h4>'; 528 echo '</div>'; 529 echo '<div class="widget-body">'; 530 echo ' <div class="widget-main no-padding">'; 531 echo '<div class="table-responsive">'; 532 echo '<table class="table table-bordered table-condensed table-striped">'; 533 echo ' <tr><td class="bold">' . lang_get( 'status' ) . '</td>'; 534 echo ' <td class="bold" >' . lang_get( 'comment' ) . '</td></tr>'; 535 echo $t_validation_result; 536 echo '</table></div></div></div></div>'; 537} 538 539# Initialization for 'reopened' label handling 540$t_resolved_status = config_get( 'bug_resolved_status_threshold' ); 541$t_reopen_status = config_get( 'bug_reopen_status' ); 542$t_reopen_label = MantisEnum::getLabel( lang_get( 'resolution_enum_string' ), config_get( 'bug_reopen_resolution' ) ); 543 544# display the graph as a matrix 545section_begin( lang_get( 'workflow' ) ); 546foreach ( $t_status_arr as $t_from_status => $t_from_label ) { 547 capability_row( $t_from_status ); 548} 549section_end(); 550 551# display the access levels required to move an issue 552echo "\n\n"; 553access_begin( lang_get( 'access_levels' ) ); 554access_row(); 555access_end(); 556echo '</div>'; 557 558if( $g_can_change_flags ) { 559 echo '<div class="col-md-12">'; 560 echo '<button class="btn btn-primary btn-white btn-round">' 561 . lang_get( 'change_configuration' ) 562 . "</button>\n"; 563 564 # Deported submit button for separate form defined below 565 # included here to simplify page layout 566 if( 0 < count( $g_overrides ) ) { 567 echo '<button form="mail_config_action" class="btn btn-primary btn-white btn-round">' 568 . lang_get( ALL_PROJECTS == $t_project ? 'revert_to_system' : 'revert_to_all_project' ) 569 . "</button>\n"; 570 } 571 echo '</div>'; 572} 573echo '</form>' . "\n"; 574 575# Secondary form to revert config - submit button is defined above 576if( $g_can_change_flags && 0 < count( $g_overrides ) ) { 577?> 578<form id="mail_config_action" method="post" action="manage_config_revert.php"> 579 <fieldset> 580 <?php echo form_security_field( 'manage_config_revert' ); ?> 581 <input name="revert" type="hidden" value="<?php echo implode( ',', $g_overrides ) ?>" /> 582 <input name="project" type="hidden" value="<?php echo $t_project ?>" /> 583 <input name="return" type="hidden" value="<?php echo string_attribute( form_action_self() ) ?>" /> 584 </fieldset> 585</form> 586 587<?php 588} 589 590layout_page_end(); 591