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 * Mantis Configuration Report 19 * @package MantisBT 20 * @copyright Copyright 2000 - 2002 Kenzaburo Ito - kenito@300baud.org 21 * @copyright Copyright 2002 MantisBT Team - mantisbt-dev@lists.sourceforge.net 22 * @link http://www.mantisbt.org 23 * 24 * @uses core.php 25 * @uses access_api.php 26 * @uses authentication_api.php 27 * @uses config_api.php 28 * @uses constant_inc.php 29 * @uses database_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 user_api.php 38 */ 39 40require_once( 'core.php' ); 41require_api( 'access_api.php' ); 42require_api( 'authentication_api.php' ); 43require_api( 'config_api.php' ); 44require_api( 'constant_inc.php' ); 45require_api( 'database_api.php' ); 46require_api( 'form_api.php' ); 47require_api( 'helper_api.php' ); 48require_api( 'html_api.php' ); 49require_api( 'lang_api.php' ); 50require_api( 'print_api.php' ); 51require_api( 'project_api.php' ); 52require_api( 'string_api.php' ); 53require_api( 'user_api.php' ); 54 55access_ensure_global_level( config_get( 'view_configuration_threshold' ) ); 56 57$t_read_write_access = access_has_global_level( config_get( 'set_configuration_threshold' ) ); 58 59require_js( 'adm_config_report.js' ); 60layout_page_header( lang_get( 'configuration_report' ) ); 61layout_page_begin( 'manage_overview_page.php' ); 62 63print_manage_menu( PAGE_CONFIG_DEFAULT ); 64print_manage_config_menu( 'adm_config_report.php' ); 65 66/** 67 * Ensures the given config is valid 68 * @param string $p_config Configuration name 69 * @return string|integer Config name if valid, or META_FILTER_NONE of not 70 */ 71function check_config_value( $p_config ) { 72 if( $p_config != META_FILTER_NONE 73 && !is_blank( $p_config ) 74 && is_null( @config_get( $p_config ) ) 75 ) { 76 return META_FILTER_NONE; 77 } 78 return $p_config; 79} 80 81# Get filter values 82$t_filter_save = gpc_get_bool( 'save' ); 83$t_filter_default = gpc_get_bool( 'default_filter_button', false ); 84$t_filter_reset = gpc_get_bool( 'reset_filter_button', false ); 85if( $t_filter_default ) { 86 $t_filter_user_value = ALL_USERS; 87 $t_filter_project_value = ALL_PROJECTS; 88 $t_filter_config_value = META_FILTER_NONE; 89} else if( $t_filter_reset ) { 90 $t_filter_user_value = META_FILTER_NONE; 91 $t_filter_project_value = META_FILTER_NONE; 92 $t_filter_config_value = META_FILTER_NONE; 93} else { 94 $t_filter_user_value = gpc_get_int( 'filter_user_id', ALL_USERS ); 95 $t_filter_project_value = gpc_get_int( 'filter_project_id', ALL_PROJECTS ); 96 $t_filter_config_value = check_config_value( gpc_get_string( 'filter_config_id', META_FILTER_NONE ) ); 97} 98 99# Manage filter's persistency through cookie 100$t_cookie_name = config_get_global( 'manage_config_cookie' ); 101if( $t_filter_save ) { 102 # Save user's filter to the cookie 103 $t_cookie_string = implode( 104 ':', 105 array( 106 $t_filter_user_value, 107 $t_filter_project_value, 108 $t_filter_config_value, 109 ) 110 ); 111 gpc_set_cookie( $t_cookie_name, $t_cookie_string, true ); 112} else { 113 # Retrieve the filter from the cookie if it exists 114 $t_cookie_string = gpc_get_cookie( $t_cookie_name, null ); 115 116 if( null !== $t_cookie_string ) { 117 $t_cookie_contents = explode( ':', $t_cookie_string ); 118 119 $t_filter_user_value = $t_cookie_contents[0]; 120 $t_filter_project_value = $t_cookie_contents[1]; 121 $t_filter_config_value = check_config_value( $t_cookie_contents[2] ); 122 123 if( $t_filter_project_value != META_FILTER_NONE && !project_exists( $t_filter_project_value ) ) { 124 $t_filter_project_value = ALL_PROJECTS; 125 } 126 } 127} 128 129# Apply filters 130 131# Get users in db having specific configs 132$t_sql = 'SELECT DISTINCT c.user_id AS config_uid, u.id, u.username, u.realname' 133 . ' FROM {config} c LEFT JOIN {user} u ON c.user_id=u.id' 134 . ' WHERE c.user_id <> :all_users ORDER BY c.user_id'; 135$t_query = new DbQuery( $t_sql, array( 'all_users' => ALL_USERS ) ); 136$t_users_list = array(); 137$t_users_ids = array(); 138$t_sort = array(); 139$t_deleted_users = array(); 140while( $t_row = $t_query->fetch() ) { 141 if( empty( $t_row['id'] ) ) { 142 # the user doesn't exist, deleted 143 $t_deleted_users[] = (int)$t_row['config_uid']; 144 continue; 145 } 146 $t_users_ids[] = (int)$t_row['id']; 147 $t_users_list[] = user_get_name_from_row( $t_row ); 148 $t_sort[] = user_get_name_for_sorting_from_row( $t_row ); 149} 150if( !empty( $t_deleted_users ) ) { 151 user_cache_array_rows( $t_deleted_users ); 152 foreach( $t_deleted_users as $t_id ) { 153 $t_users_ids[] = $t_id; 154 $t_name = user_get_name( $t_id ); 155 $t_users_list[] = $t_name; 156 $t_sort[] = $t_name; 157 } 158} 159if( $t_filter_user_value != META_FILTER_NONE && $t_filter_user_value != ALL_USERS ) { 160 # Make sure the filter value exists in the list 161 $t_row = user_get_row( $t_filter_user_value ); 162 $t_users_ids[] = $t_filter_user_value; 163 $t_users_list[] = user_get_name_from_row( $t_row ); 164 $t_sort[] = user_get_name_for_sorting_from_row( $t_row ); 165} 166user_cache_array_rows( $t_users_ids ); 167array_multisort( $t_sort, SORT_ASC, SORT_NATURAL | SORT_FLAG_CASE, $t_users_list, $t_users_ids ); 168$t_users_list = array_combine( $t_users_ids, $t_users_list ); 169 170# Prepend '[any]' and 'All Users' to the list 171$t_users_list = array( 172 META_FILTER_NONE => '[' . lang_get( 'any' ) . ']', 173 ALL_USERS => lang_get( 'all_users' ), 174 ) 175 + $t_users_list; 176 177# Get projects in db with specific configs 178$t_query = 'SELECT DISTINCT project_id, pt.name as project_name 179 FROM {config} ct 180 JOIN {project} pt ON pt.id = ct.project_id 181 WHERE project_id!=0 182 ORDER BY project_name'; 183$t_result = db_query( $t_query ); 184$t_projects_list[META_FILTER_NONE] = '[' . lang_get( 'any' ) . ']'; 185$t_projects_list[ALL_PROJECTS] = lang_get( 'all_projects' ); 186while( $t_row = db_fetch_array( $t_result ) ) { 187 /** 188 * @var integer $v_project_id 189 * @var string $v_project_name 190 */ 191 extract( $t_row, EXTR_PREFIX_ALL, 'v' ); 192 $t_projects_list[$v_project_id] = $v_project_name; 193} 194 195# Get config list used in db 196$t_query = 'SELECT DISTINCT config_id FROM {config} ORDER BY config_id'; 197$t_result = db_query( $t_query ); 198$t_configs_list[META_FILTER_NONE] = '[' . lang_get( 'any' ) . ']'; 199if( $t_filter_config_value != META_FILTER_NONE ) { 200 # Make sure the filter value exists in the list 201 $t_configs_list[$t_filter_config_value] = $t_filter_config_value; 202} 203while( $t_row = db_fetch_array( $t_result ) ) { 204 /** 205 * @var string $v_config_id 206 */ 207 extract( $t_row, EXTR_PREFIX_ALL, 'v' ); 208 $t_configs_list[$v_config_id] = $v_config_id; 209} 210 211# Build config query 212$t_sql = 'SELECT config_id, user_id, project_id, type, access_reqd,' 213 . ' CASE type WHEN :complex THEN null ELSE value END AS value' 214 . ' FROM {config} WHERE 1=1'; 215if( $t_filter_user_value != META_FILTER_NONE ) { 216 $t_sql .= ' AND user_id = :user_id'; 217} 218if( $t_filter_project_value != META_FILTER_NONE ) { 219 $t_sql .= ' AND project_id = :project_id'; 220} 221if( $t_filter_config_value != META_FILTER_NONE ) { 222 $t_sql .= ' AND config_id = :config_id'; 223} 224$t_sql .= ' ORDER BY user_id, project_id, config_id '; 225$t_params = array( 226 'user_id' => $t_filter_user_value, 227 'project_id' => $t_filter_project_value, 228 'config_id' => $t_filter_config_value, 229 'complex' => CONFIG_TYPE_COMPLEX 230 ); 231$t_config_query = new DbQuery( $t_sql, $t_params ); 232?> 233 234<div class="col-md-12 col-xs-12"> 235<div class="space-10"></div> 236 237<!-- FILTER FORM --> 238<form id="filter_form" method="post"> 239 <?php # CSRF protection not required here - form does not result in modifications ?> 240 <input type="hidden" name="save" value="1" /> 241 242<div class="widget-box widget-color-blue2"> 243<div class="widget-header widget-header-small"> 244<h4 class="widget-title lighter"> 245 <?php print_icon( 'fa-filter', 'ace-icon' ); ?> 246 <?php echo lang_get( 'filters' ) ?> 247</h4> 248</div> 249 250<div class="widget-body"> 251<div class="widget-main no-padding"> 252 <div class="table-responsive"> 253 <table class="table table-striped table-bordered table-condensed"> 254 <!-- Title --> 255 <thead> 256 <tr> 257 <th> 258 <?php echo lang_get( 'username' ); ?><br /> 259 </th> 260 <th> 261 <?php echo lang_get( 'project_name' ); ?><br /> 262 </th> 263 <th> 264 <?php echo lang_get( 'configuration_option' ); ?><br /> 265 </th> 266 </tr> 267 </thead> 268 269 <tbody> 270 <tr> 271 <td> 272 <select name="filter_user_id" class="input-sm"> 273 <?php 274 print_option_list_from_array( $t_users_list, $t_filter_user_value ); 275 ?> 276 </select> 277 </td> 278 <td> 279 <select name="filter_project_id" class="input-sm"> 280 <?php 281 print_option_list_from_array( $t_projects_list, $t_filter_project_value ); 282 ?> 283 </select> 284 </td> 285 <td> 286 <select name="filter_config_id" class="input-sm"> 287 <?php 288 print_option_list_from_array( $t_configs_list, $t_filter_config_value ); 289 ?> 290 </select> 291 </td> 292 </tr> 293 </tbody> 294 </table> 295</div> 296</div> 297<div class="widget-toolbox padding-8 clearfix"> 298 <div class="btn-toolbar"> 299 <div class="btn-group"> 300 <input name="apply_filter_button" type="submit" class="btn btn-sm btn-primary btn-white btn-round" 301 value="<?php echo lang_get( 'filter_button' )?>" /> 302 303 <input name="default_filter_button" type="submit" class="btn btn-sm btn-primary btn-white btn-round" 304 value="<?php echo lang_get( 'default_filter' )?>" /> 305 306 <input name="reset_filter_button" type="submit" class="btn btn-sm btn-primary btn-white btn-round" 307 value="<?php echo lang_get( 'reset_query' )?>" /> 308 </div> 309 </div> 310</div> 311</div> 312</div> 313</form> 314 315 316<div class="space-10"></div> 317 318<!-- CONFIGURATIONS LIST --> 319<a id="database_configuration"></a> 320<div class="widget-box widget-color-blue2"> 321<div class="widget-header widget-header-small"> 322<h4 class="widget-title lighter"> 323 <?php print_icon( 'fa-database', 'ace-icon' ); ?> 324 <?php echo lang_get( 'database_configuration' ) ?> 325</h4> 326</div> 327 328<div class="widget-body"> 329<div class="widget-main no-padding"> 330 <div class="widget-toolbox padding-8 clearfix"> 331 <?php 332 $t_url_new = 'adm_config_page.php?action=' . MANAGE_CONFIG_ACTION_CREATE; 333 $t_label = lang_get( 'set_configuration_option_action_' . MANAGE_CONFIG_ACTION_CREATE ); 334 print_link_button( $t_url_new, $t_label ); 335 336 print_link_button( 337 '#database_configuration', 338 sprintf( lang_get( 'show_all_complex' ), config_get_type_string( CONFIG_TYPE_COMPLEX ) ), 339 'expand_all' 340 ); 341 ?> 342 </div> 343<div class="table-responsive sortable"> 344 <table class="table table-striped table-bordered table-condensed table-hover"> 345 <thead> 346 <tr> 347 <th><?php echo lang_get( 'username' ) ?></th> 348 <th><?php echo lang_get( 'project_name' ) ?></th> 349 <th><?php echo lang_get( 'configuration_option' ) ?></th> 350 <th><?php echo lang_get( 'configuration_option_type' ) ?></th> 351 <th><?php echo lang_get( 'configuration_option_value' ) ?></th> 352 <th><?php echo lang_get( 'access_level' ) ?></th> 353 <?php if( $t_read_write_access ) { ?> 354 <th class="no-sort"><?php echo lang_get( 'actions' ) ?></th> 355 <?php } ?> 356 </tr> 357 </thead> 358 359 <tbody> 360<?php 361# Pre-generate a form security token to avoid performance issues when the 362# db contains a large number of configurations 363$t_form_security_token = form_security_token( 'adm_config_delete' ); 364 365while( $t_row = $t_config_query->fetch() ) { 366 /** 367 * @var integer $v_type 368 * @var integer $v_user_id 369 * @var integer $v_project_id 370 * @var string $v_config_id 371 * @var mixed $v_value 372 * @var integer $v_access_reqd 373 */ 374 extract( $t_row, EXTR_PREFIX_ALL, 'v' ); 375 376 # For complex values, the content is not rendered 377 if( CONFIG_TYPE_COMPLEX == $v_type ) { 378 $t_url_params = array( 379 'user_id' => $v_user_id, 380 'project_id' => $v_project_id, 381 'config_option' => $v_config_id, 382 'action' => MANAGE_CONFIG_ACTION_VIEW 383 ); 384 $t_url_view = helper_url_combine( 'adm_config_page.php', http_build_query( $t_url_params ) ); 385 $t_html_value = '<div class="adm_config_expand" data-config_id="' . $v_config_id . '"' 386 . ' data-project_id="' . $v_project_id . '" data-user_id="' . $v_user_id . '">' 387 . '<span class ="expand_show"><a href="' . $t_url_view . '" class="toggle small">[' . lang_get( 'show_content' ) . ']</a></span>' 388 . '<span class ="expand_hide hidden"><a href="#" class="toggle small">[' . lang_get( 'hide_content' ) . ']</a></span>' 389 . '<div class="expand_content"></div>' 390 . '</div>'; 391 } else { 392 $t_html_value = config_get_value_as_string( $v_type, $v_value ); 393 } 394 395?> 396<!-- Repeated Info Rows --> 397 <tr class="visible-on-hover-toggle"> 398 <td> 399 <?php echo ($v_user_id == 0) ? lang_get( 'all_users' ) : string_display_line( user_get_name( $v_user_id ) ) ?> 400 </td> 401 <td><?php echo string_display_line( project_get_name( $v_project_id, false ) ) ?></td> 402 <td><?php echo string_display_line( $v_config_id ) ?></td> 403 <td><?php echo string_display_line( config_get_type_string( $v_type ) ) ?></td> 404 <td style="overflow-x:auto;"><?php echo $t_html_value ?></td> 405 <td><?php echo get_enum_element( 'access_levels', $v_access_reqd ) ?></td> 406<?php 407 if( $t_read_write_access ) { 408?> 409<td class="center"> 410 <div class="btn-group inline visible-on-hover"> 411<?php 412 if( config_can_delete( $v_config_id ) ) { 413 $t_action_params = array( 414 'user_id' => $v_user_id, 415 'project_id' => $v_project_id, 416 'config_option' => $v_config_id, 417 ); 418 419 # Update button 420 $t_action_params['action'] = MANAGE_CONFIG_ACTION_EDIT; 421 $t_url_edit = helper_url_combine( 'adm_config_page.php', http_build_query( $t_action_params ) ); 422 echo '<div class="pull-left">'; 423 print_link_button( $t_url_edit, lang_get( 'edit' ), 'btn-xs' ); 424 echo '</div>'; 425 426 # Clone button 427 echo '<div class="pull-left">'; 428 $t_action_params['action'] = MANAGE_CONFIG_ACTION_CLONE; 429 $t_url_clone = helper_url_combine( 'adm_config_page.php', http_build_query( $t_action_params ) ); 430 print_link_button( $t_url_clone, lang_get( 'create_child_bug_button' ), 'btn-xs' ); 431 echo '</div>'; 432 433 # Delete button 434 echo '<div class="pull-left">'; 435 print_form_button( 436 'adm_config_delete.php', 437 lang_get( 'delete' ), 438 array( 439 'user_id' => $v_user_id, 440 'project_id' => $v_project_id, 441 'config_option' => $v_config_id, 442 ), 443 $t_form_security_token 444 ); 445 echo '</div>'; 446 } else { 447 echo ' '; 448 } 449?> 450 </div> 451 </td> 452<?php 453 } # end if config_can_delete 454?> 455 </tr> 456<?php 457} # end while loop 458?> 459 </tbody> 460 </table> 461</div> 462</div> 463</div> 464</div> 465 466</div> 467 468<?php 469layout_page_end(); 470