View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0021810 | mantisbt | ui | public | 2016-10-19 08:20 | 2016-10-30 03:38 |
Reporter | nebjanim | Assigned To | atrol | ||
Priority | high | Severity | tweak | Reproducibility | always |
Status | closed | Resolution | duplicate | ||
Product Version | 1.3.2 | ||||
Summary | 0021810: Sorting of values in drop down menues should be done by alphabet and not by registration into the database | ||||
Description | Sorting of values in drop down menues should be done by alphabet and not by registration into the database. I've managed this by a simple change in print_api.php. Please find attached the original file and the changed file for version mantis 1.3.2. | ||||
Tags | No tags attached. | ||||
Attached Files | print_api.php (71,614 bytes)
<?php # MantisBT - A PHP based bugtracking system # MantisBT is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # MantisBT is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with MantisBT. If not, see <http://www.gnu.org/licenses/>. /** * Print API * * @package CoreAPI * @subpackage PrintAPI * @copyright Copyright 2000 - 2002 Kenzaburo Ito - kenito@300baud.org * @copyright Copyright 2002 MantisBT Team - mantisbt-dev@lists.sourceforge.net * @link http://www.mantisbt.org * * @uses access_api.php * @uses authentication_api.php * @uses bug_group_action_api.php * @uses category_api.php * @uses config_api.php * @uses collapse_api.php * @uses constant_inc.php * @uses current_user_api.php * @uses custom_field_api.php * @uses database_api.php * @uses email_api.php * @uses error_api.php * @uses file_api.php * @uses form_api.php * @uses helper_api.php * @uses html_api.php * @uses lang_api.php * @uses last_visited_api.php * @uses news_api.php * @uses prepare_api.php * @uses profile_api.php * @uses project_api.php * @uses project_hierarchy_api.php * @uses string_api.php * @uses tag_api.php * @uses user_api.php * @uses utility_api.php * @uses version_api.php */ require_api( 'access_api.php' ); require_api( 'authentication_api.php' ); require_api( 'bug_group_action_api.php' ); require_api( 'category_api.php' ); require_api( 'config_api.php' ); require_api( 'collapse_api.php' ); require_api( 'constant_inc.php' ); require_api( 'current_user_api.php' ); require_api( 'custom_field_api.php' ); require_api( 'database_api.php' ); require_api( 'email_api.php' ); require_api( 'error_api.php' ); require_api( 'file_api.php' ); require_api( 'form_api.php' ); require_api( 'helper_api.php' ); require_api( 'html_api.php' ); require_api( 'lang_api.php' ); require_api( 'last_visited_api.php' ); require_api( 'news_api.php' ); require_api( 'prepare_api.php' ); require_api( 'profile_api.php' ); require_api( 'project_api.php' ); require_api( 'project_hierarchy_api.php' ); require_api( 'string_api.php' ); require_api( 'tag_api.php' ); require_api( 'user_api.php' ); require_api( 'utility_api.php' ); require_api( 'version_api.php' ); /** * Print the headers to cause the page to redirect to $p_url * If $p_die is true (default), terminate the execution of the script immediately * If we have handled any errors on this page return false and don't redirect. * $p_sanitize - true/false - true in the case where the URL is extracted from GET/POST or untrusted source. * This would be false if the URL is trusted (e.g. read from config_inc.php). * * @param string $p_url The page to redirect: has to be a relative path. * @param boolean $p_die If true, stop the script after redirecting. * @param boolean $p_sanitize Apply string_sanitize_url to passed URL. * @param boolean $p_absolute Indicate if URL is absolute. * @return boolean */ function print_header_redirect( $p_url, $p_die = true, $p_sanitize = false, $p_absolute = false ) { if( ON == config_get_global( 'stop_on_errors' ) && error_handled() ) { return false; } # validate the url as part of this site before continuing if( $p_absolute ) { if( $p_sanitize ) { $t_url = string_sanitize_url( $p_url ); } else { $t_url = $p_url; } } else { if( $p_sanitize ) { $t_url = string_sanitize_url( $p_url, true ); } else { $t_url = config_get( 'path' ) . $p_url; } } $t_url = string_prepare_header( $t_url ); # don't send more headers if they have already been sent if( !headers_sent() ) { header( 'Content-Type: text/html; charset=utf-8' ); header( 'Location: ' . $t_url ); } else { trigger_error( ERROR_PAGE_REDIRECTION, ERROR ); return false; } if( $p_die ) { die; # additional output can cause problems so let's just stop output here } return true; } /** * Print a redirect header to view a bug * * @param integer $p_bug_id A bug identifier. * @return void */ function print_header_redirect_view( $p_bug_id ) { print_header_redirect( string_get_bug_view_url( $p_bug_id ) ); } /** * Get a view URL for the bug id based on the user's preference and * call print_successful_redirect() with that URL * * @param integer $p_bug_id A bug identifier. * @return void */ function print_successful_redirect_to_bug( $p_bug_id ) { $t_url = string_get_bug_view_url( $p_bug_id ); print_successful_redirect( $t_url ); } /** * If the show query count is ON, print success and redirect after the configured system wait time. * If the show query count is OFF, redirect right away. * * @param string $p_redirect_to URI to redirect to. * @return void */ function print_successful_redirect( $p_redirect_to ) { if( helper_log_to_page() ) { html_page_top( null, $p_redirect_to ); echo '<br /><div class="center">'; echo lang_get( 'operation_successful' ) . '<br />'; print_bracket_link( $p_redirect_to, lang_get( 'proceed' ) ); echo '</div>'; html_page_bottom(); } else { print_header_redirect( $p_redirect_to ); } } /** * Print avatar image for the given user ID * * @param integer $p_user_id A user identifier. * @param integer $p_size Image pixel size. * @return void */ function print_avatar( $p_user_id, $p_size = 80 ) { $t_avatar = Avatar::get( $p_user_id, $p_size ); if( $t_avatar === null ) { return; } $t_image = htmlspecialchars( $t_avatar->image ); $t_link = htmlspecialchars( $t_avatar->link ); $t_text = htmlspecialchars( $t_avatar->text ); echo '<a rel="nofollow" href="' . $t_link . '">' . '<img class="avatar" src="' . $t_image . '" alt="' . $t_text . '" width="' . $p_size . '" height="' . $p_size . '" /></a>'; } /** * prints the name of the user given the id. also makes it an email link. * * @param integer $p_user_id A user identifier. * @return void */ function print_user( $p_user_id ) { echo prepare_user_name( $p_user_id ); } /** * same as echo get_user_name() but fills in the subject with the bug summary * * @param integer $p_user_id A user identifier. * @param integer $p_bug_id A bug identifier. * @return void */ function print_user_with_subject( $p_user_id, $p_bug_id ) { if( NO_USER == $p_user_id ) { return; } $t_username = user_get_name( $p_user_id ); if( user_exists( $p_user_id ) && user_get_field( $p_user_id, 'enabled' ) ) { $t_email = user_get_email( $p_user_id ); print_email_link_with_subject( $t_email, $t_username, $p_bug_id ); } else { echo '<span class="user" style="text-decoration: line-through">'; echo $t_username; echo '</span>'; } } /** * print out an email editing input * * @param string $p_field_name Name of input tag. * @param string $p_email Email address. * @return void */ function print_email_input( $p_field_name, $p_email ) { echo '<input id="email-field" type="text" name="' . string_attribute( $p_field_name ) . '" size="32" maxlength="64" value="' . string_attribute( $p_email ) . '" />'; } /** * print out an email editing input * * @param string $p_field_name Name of input tag. * @return void */ function print_captcha_input( $p_field_name ) { echo '<input id="captcha-field" type="text" name="' . $p_field_name . '" size="6" maxlength="6" value="" />'; } /** * This populates an option list with the appropriate users by access level * @todo from print_reporter_option_list * @param integer|array $p_user_id A user identifier or a list of them. * @param integer $p_project_id A project identifier. * @param integer $p_access An access level. * @return void */ function print_user_option_list( $p_user_id, $p_project_id = null, $p_access = ANYBODY ) { $t_current_user = auth_get_current_user_id(); if( null === $p_project_id ) { $p_project_id = helper_get_current_project(); } if( $p_project_id === ALL_PROJECTS ) { $t_projects = user_get_accessible_projects( $t_current_user ); # Get list of users having access level for all accessible projects $t_users = array(); foreach( $t_projects as $t_project_id ) { $t_project_users_list = project_get_all_user_rows( $t_project_id, $p_access ); # Do a 'smart' merge of the project's user list, into an # associative array (to remove duplicates) foreach( $t_project_users_list as $t_id => $t_user ) { $t_users[$t_id] = $t_user; } # Clear the array to release memory unset( $t_project_users_list ); } unset( $t_projects ); } else { $t_users = project_get_all_user_rows( $p_project_id, $p_access ); } # Add the specified user ID to the list # If we have an array of user IDs, then we've been called from a filter # so don't add anything if( !is_array( $p_user_id ) && $p_user_id != NO_USER && !array_key_exists( $p_user_id, $t_users ) ) { $t_row = user_cache_row( $p_user_id, /* trigger_error */ false ); if( $t_row === false ) { # User doesn't exist - create a dummy record for display purposes $t_name = user_get_name( $p_user_id ); $t_row = array( 'id' => $p_user_id, 'username' => $t_name, 'realname' => $t_name, ); } $t_users[$p_user_id] = $t_row; } $t_display = array(); $t_sort = array(); $t_show_realname = ( ON == config_get( 'show_realname' ) ); $t_sort_by_last_name = ( ON == config_get( 'sort_by_last_name' ) ); foreach( $t_users as $t_key => $t_user ) { $t_user_name = string_attribute( $t_user['username'] ); $t_sort_name = utf8_strtolower( $t_user_name ); if( $t_show_realname && ( $t_user['realname'] <> '' ) ) { $t_user_name = string_attribute( $t_user['realname'] ); if( $t_sort_by_last_name ) { $t_sort_name_bits = explode( ' ', utf8_strtolower( $t_user_name ), 2 ); $t_sort_name = ( isset( $t_sort_name_bits[1] ) ? $t_sort_name_bits[1] . ', ' : '' ) . $t_sort_name_bits[0]; } else { $t_sort_name = utf8_strtolower( $t_user_name ); } } $t_display[] = $t_user_name; $t_sort[] = $t_sort_name; } array_multisort( $t_sort, SORT_ASC, SORT_STRING, $t_users, $t_display ); unset( $t_sort ); $t_count = count( $t_users ); for( $i = 0;$i < $t_count;$i++ ) { $t_row = $t_users[$i]; echo '<option value="' . $t_row['id'] . '" '; check_selected( $p_user_id, (int)$t_row['id'] ); echo '>' . $t_display[$i] . '</option>'; } } /** * This populates the reporter option list with the appropriate users * * @todo ugly functions need to be refactored * @todo This function really ought to print out all the users, I think. * I just encountered a situation where a project used to be public and * was made private, so now I can't filter on any of the reporters who * actually reported the bugs at the time. Maybe we could get all user * who are listed as the reporter in any bug? It would probably be a * faster query actually. * @param integer $p_user_id A user identifier. * @param integer $p_project_id A project identifier. * @return void */ function print_reporter_option_list( $p_user_id, $p_project_id = null ) { print_user_option_list( $p_user_id, $p_project_id, config_get( 'report_bug_threshold' ) ); } /** * Print the entire form for attaching a tag to a bug. * @param integer $p_bug_id A bug identifier. * @param string $p_string Default contents of the input box. * @return boolean */ function print_tag_attach_form( $p_bug_id, $p_string = '' ) { ?> <small><?php echo sprintf( lang_get( 'tag_separate_by' ), config_get( 'tag_separator' ) )?></small> <form method="post" action="tag_attach.php"> <?php echo form_security_field( 'tag_attach' )?> <input type="hidden" name="bug_id" value="<?php echo $p_bug_id?>" /> <?php print_tag_input( $p_bug_id, $p_string ); ?> <input type="submit" value="<?php echo lang_get( 'tag_attach' )?>" class="button" /> </form> <?php return true; } /** * Print the separator comment, input box, and existing tag dropdown menu. * @param integer $p_bug_id A bug identifier. * @param string $p_string Default contents of the input box. * @return void */ function print_tag_input( $p_bug_id = 0, $p_string = '' ) { ?> <input type="hidden" id="tag_separator" value="<?php echo config_get( 'tag_separator' )?>" /> <input type="text" name="tag_string" id="tag_string" size="40" value="<?php echo string_attribute( $p_string )?>" /> <select <?php echo helper_get_tab_index()?> name="tag_select" id="tag_select"> <?php print_tag_option_list( $p_bug_id );?> </select> <?php } /** * Print out a list of errors for tags that failed validation or access check. * * @param array $p_tags_failed The array of failed tags. * @return void */ function print_tagging_errors_table( $p_tags_failed ) { ?> <div id="manage-user-div" class="form-container"> <h2><?php echo lang_get( 'tag_attach_failed' ) ?></h2> <table><tbody> <?php foreach( $p_tags_failed as $t_tag_row ) { echo '<tr>'; echo '<td>', string_html_specialchars( $t_tag_row['name'] ), '</td>'; if( -1 == $t_tag_row['id'] ) { $t_error = lang_get( 'tag_create_denied' ); } else if( -2 == $t_tag_row['id'] ) { $t_error = lang_get( 'tag_invalid_name' ); } echo '<td>', $t_error, '</td>'; echo '</tr>'; } ?> </tbody></table> </div> <?php } /** * Print the drop-down combo-box of existing tags. * When passed a bug ID, the option list will not contain any tags attached to the given bug. * @param integer $p_bug_id A bug identifier. * @return void */ function print_tag_option_list( $p_bug_id = 0 ) { $t_rows = tag_get_candidates_for_bug( $p_bug_id ); echo '<option value="0">', string_html_specialchars( lang_get( 'tag_existing' ) ), '</option>'; foreach ( $t_rows as $t_row ) { echo '<option value="', $t_row['id'], '" title="', string_attribute( $t_row['description'] ); echo '">', string_attribute( $t_row['name'] ), '</option>'; } } /** * Get current headlines and id prefix with v_ * @return void */ function print_news_item_option_list() { $t_project_id = helper_get_current_project(); $t_global = access_has_global_level( config_get_global( 'admin_site_threshold' ) ); db_param_push(); if( $t_global ) { $t_query = 'SELECT id, headline, announcement, view_state FROM {news} ORDER BY date_posted DESC'; } else { $t_query = 'SELECT id, headline, announcement, view_state FROM {news} WHERE project_id=' . db_param() . ' ORDER BY date_posted DESC'; } $t_result = db_query( $t_query, ($t_global == true ? array() : array( $t_project_id ) ) ); while( $t_row = db_fetch_array( $t_result ) ) { $t_headline = string_display( $t_row['headline'] ); $t_announcement = $t_row['announcement']; $t_view_state = $t_row['view_state']; $t_id = $t_row['id']; $t_notes = array(); $t_note_string = ''; if( 1 == $t_announcement ) { array_push( $t_notes, lang_get( 'announcement' ) ); } if( VS_PRIVATE == $t_view_state ) { array_push( $t_notes, lang_get( 'private' ) ); } if( count( $t_notes ) > 0 ) { $t_note_string = ' [' . implode( ' ', $t_notes ) . ']'; } echo '<option value="' . $t_id . '">' . $t_headline . $t_note_string . '</option>'; } } /** * Constructs the string for one news entry given the row retrieved from the news table. * * @param string $p_headline Headline of news article. * @param string $p_body Body text of news article. * @param integer $p_poster_id User ID of author. * @param integer $p_view_state View State - either VS_PRIVATE or VS_PUBLIC. * @param boolean $p_announcement Flagged if news should be an announcement. * @param integer $p_date_posted Date associated with news entry. * @return void */ function print_news_entry( $p_headline, $p_body, $p_poster_id, $p_view_state, $p_announcement, $p_date_posted ) { $t_headline = string_display_links( $p_headline ); $t_body = string_display_links( $p_body ); $t_date_posted = date( config_get( 'normal_date_format' ), $p_date_posted ); if( VS_PRIVATE == $p_view_state ) { $t_news_css = 'news-heading-private'; } else { $t_news_css = 'news-heading-public'; } ?> <div class="news-item"> <h3 class="<?php echo $t_news_css; ?>"> <span class="news-title"><?php echo $t_headline; ?></span> <span class="news-date-posted"><?php echo $t_date_posted; ?></span> <span class="news-author"><?php echo prepare_user_name( $p_poster_id ); ?></span><?php if( 1 == $p_announcement ) { ?> <span class="news-announcement"><?php echo lang_get( 'announcement' ); ?></span><?php } if( VS_PRIVATE == $p_view_state ) { ?> <span class="news-private"><?php echo lang_get( 'private' ); ?></span><?php } ?> </h3> <p class="news-body"><?php echo $t_body; ?></p> </div><?php } /** * print a news item given a row in the news table. * @param array $p_news_row A news database result. * @return void */ function print_news_entry_from_row( array $p_news_row ) { $t_headline = $p_news_row['headline']; $t_body = $p_news_row['body']; $t_poster_id = $p_news_row['poster_id']; $t_view_state = $p_news_row['view_state']; $t_announcement = $p_news_row['announcement']; $t_date_posted = $p_news_row['date_posted']; print_news_entry( $t_headline, $t_body, $t_poster_id, $t_view_state, $t_announcement, $t_date_posted ); } /** * print a news item * * @param integer $p_news_id A news article identifier. * @return void */ function print_news_string_by_news_id( $p_news_id ) { $t_row = news_get_row( $p_news_id ); # only show VS_PRIVATE posts to configured threshold and above if( ( VS_PRIVATE == $t_row['view_state'] ) && !access_has_project_level( config_get( 'private_news_threshold' ) ) ) { return; } print_news_entry_from_row( $t_row ); } /** * Print User option list for assigned to field * @param integer|string $p_user_id A user identifier. * @param integer $p_project_id A project identifier. * @param integer $p_threshold An access level. * @return void */ function print_assign_to_option_list( $p_user_id = '', $p_project_id = null, $p_threshold = null ) { if( null === $p_threshold ) { $p_threshold = config_get( 'handle_bug_threshold' ); } print_user_option_list( $p_user_id, $p_project_id, $p_threshold ); } /** * Print User option list for bugnote filter field * @param integer|string $p_user_id A user identifier. * @param integer $p_project_id A project identifier. * @param integer $p_threshold An access level. * @return void */ function print_note_option_list( $p_user_id = '', $p_project_id = null, $p_threshold = null ) { if( null === $p_threshold ) { $p_threshold = config_get( 'add_bugnote_threshold' ); } print_user_option_list( $p_user_id, $p_project_id, $p_threshold ); } /** * List projects that the current user has access to. * * @param integer $p_project_id The current project id or null to use cookie. * @param boolean $p_include_all_projects True: include "All Projects", otherwise false. * @param integer|null $p_filter_project_id The id of a project to exclude or null. * @param string|boolean $p_trace The current project trace, identifies the sub-project via a path from top to bottom. * @param boolean $p_can_report_only If true, disables projects in which user can't report issues; defaults to false (all projects enabled). * @return void */ function print_project_option_list( $p_project_id = null, $p_include_all_projects = true, $p_filter_project_id = null, $p_trace = false, $p_can_report_only = false ) { $t_user_id = auth_get_current_user_id(); $t_project_ids = user_get_accessible_projects( $t_user_id ); $t_can_report = true; project_cache_array_rows( $t_project_ids ); if( $p_include_all_projects && $p_filter_project_id !== ALL_PROJECTS ) { echo '<option value="' . ALL_PROJECTS . '"'; if( $p_project_id !== null ) { check_selected( $p_project_id, ALL_PROJECTS, false ); } echo '>' . lang_get( 'all_projects' ) . '</option>' . "\n"; } foreach( $t_project_ids as $t_id ) { if( $p_can_report_only ) { $t_report_bug_threshold = config_get( 'report_bug_threshold', null, $t_user_id, $t_id ); $t_can_report = access_has_project_level( $t_report_bug_threshold, $t_id, $t_user_id ); } echo '<option value="' . $t_id . '"'; check_selected( $p_project_id, $t_id, false ); check_disabled( $t_id == $p_filter_project_id || !$t_can_report ); echo '>' . string_attribute( project_get_field( $t_id, 'name' ) ) . '</option>' . "\n"; print_subproject_option_list( $t_id, $p_project_id, $p_filter_project_id, $p_trace, $p_can_report_only ); } } /** * List projects that the current user has access to * @param integer $p_parent_id A parent project identifier. * @param integer $p_project_id A project identifier. * @param integer $p_filter_project_id A filter project identifier. * @param boolean $p_trace Whether to trace parent projects. * @param boolean $p_can_report_only If true, disables projects in which user can't report issues; defaults to false (all projects enabled). * @param array $p_parents Array of parent projects. * @return void */ function print_subproject_option_list( $p_parent_id, $p_project_id = null, $p_filter_project_id = null, $p_trace = false, $p_can_report_only = false, array $p_parents = array() ) { if ( config_get( 'subprojects_enabled' ) == OFF ) { return; } array_push( $p_parents, $p_parent_id ); $t_user_id = auth_get_current_user_id(); $t_project_ids = user_get_accessible_subprojects( $t_user_id, $p_parent_id ); project_cache_array_rows( $t_project_ids ); $t_can_report = true; foreach( $t_project_ids as $t_id ) { if( $p_can_report_only ) { $t_report_bug_threshold = config_get( 'report_bug_threshold', null, $t_user_id, $t_id ); $t_can_report = access_has_project_level( $t_report_bug_threshold, $t_id, $t_user_id ); } if( $p_trace ) { $t_full_id = join( $p_parents, ';' ) . ';' . $t_id; } else { $t_full_id = $t_id; } echo '<option value="' . $t_full_id . '"'; check_selected( $p_project_id, $t_full_id, false ); check_disabled( $t_id == $p_filter_project_id || !$t_can_report ); echo '>' . str_repeat( ' ', count( $p_parents ) ) . str_repeat( '»', count( $p_parents ) ) . ' ' . string_attribute( project_get_field( $t_id, 'name' ) ) . '</option>' . "\n"; print_subproject_option_list( $t_id, $p_project_id, $p_filter_project_id, $p_trace, $p_can_report_only, $p_parents ); } } /** * prints the profiles given the user id * @param integer $p_user_id A user identifier. * @param integer $p_select_id ID to mark as selected; if 0, gets the user's default profile. * @param array $p_profiles Array of profiles. * @return void */ function print_profile_option_list( $p_user_id, $p_select_id = 0, array $p_profiles = null ) { if( 0 == $p_select_id ) { $p_select_id = profile_get_default( $p_user_id ); } if( $p_profiles != null ) { $t_profiles = $p_profiles; } else { $t_profiles = profile_get_all_for_user( $p_user_id ); } print_profile_option_list_from_profiles( $t_profiles, $p_select_id ); } /** * prints the profiles used in a certain project * @param integer $p_project_id A project identifier. * @param integer $p_select_id ID to mark as selected; if 0, gets the user's default profile. * @param array $p_profiles Array of profiles. * @return void */ function print_profile_option_list_for_project( $p_project_id, $p_select_id = 0, array $p_profiles = null ) { if( 0 == $p_select_id ) { $p_select_id = profile_get_default( auth_get_current_user_id() ); } if( $p_profiles != null ) { $t_profiles = $p_profiles; } else { $t_profiles = profile_get_all_for_project( $p_project_id ); } print_profile_option_list_from_profiles( $t_profiles, $p_select_id ); } /** * print the profile option list from profiles array * * @param array $p_profiles Array of Operating System Profiles (ID, platform, os, os_build). * @param integer $p_select_id ID to mark as selected. * @return void */ function print_profile_option_list_from_profiles( array $p_profiles, $p_select_id ) { echo '<option value="">' . lang_get( 'select_option' ) . '</option>'; foreach( $p_profiles as $t_profile ) { extract( $t_profile, EXTR_PREFIX_ALL, 'v' ); $t_platform = string_attribute( $t_profile['platform'] ); $t_os = string_attribute( $t_profile['os'] ); $t_os_build = string_attribute( $t_profile['os_build'] ); echo '<option value="' . $t_profile['id'] . '"'; if( $p_select_id !== false ) { check_selected( $p_select_id, (int)$t_profile['id'] ); } echo '>' . $t_platform . ' ' . $t_os . ' ' . $t_os_build . '</option>'; } } /** * Since categories can be orphaned we need to grab all unique instances of category * We check in the project category table and in the bug table * We put them all in one array and make sure the entries are unique * * @param integer $p_category_id A category identifier. * @param integer $p_project_id A project identifier. * @return void */ function print_category_option_list( $p_category_id = 0, $p_project_id = null ) { if( null === $p_project_id ) { $t_project_id = helper_get_current_project(); } else { $t_project_id = $p_project_id; } $t_cat_arr = category_get_all_rows( $t_project_id, null, true ); if( config_get( 'allow_no_category' ) ) { echo '<option value="0"'; check_selected( $p_category_id, 0 ); echo '>'; echo category_full_name( 0, false ), '</option>'; } else { if( 0 == $p_category_id ) { if( count( $t_cat_arr ) == 1 ) { $p_category_id = (int) $t_cat_arr[0]['id']; } else { echo '<option value="0"'; echo check_selected( $p_category_id, 0 ); echo '>'; echo string_attribute( lang_get( 'select_option' ) ) . '</option>'; } } } foreach( $t_cat_arr as $t_category_row ) { $t_category_id = (int)$t_category_row['id']; echo '<option value="' . $t_category_id . '"'; check_selected( $p_category_id, $t_category_id ); echo '>' . string_attribute( category_full_name( $t_category_id, $t_category_row['project_id'] != $t_project_id ) ) . '</option>'; } } /** * Now that categories are identified by numerical ID, we need an old-style name * based option list to keep existing filter functionality. * @param string $p_category_name The selected category. * @param integer|null $p_project_id A specific project or null. * @return void */ function print_category_filter_option_list( $p_category_name = '', $p_project_id = null ) { $t_cat_arr = category_get_filter_list( $p_project_id ); natcasesort( $t_cat_arr ); foreach( $t_cat_arr as $t_cat ) { $t_name = string_attribute( $t_cat ); echo '<option value="' . $t_name . '"'; check_selected( $p_category_name, $t_cat ); echo '>' . $t_name . '</option>'; } } /** * Print the option list for platforms accessible for the specified user. * @param string $p_platform The current platform value. * @param integer $p_user_id A user identifier. * @return void */ function print_platform_option_list( $p_platform, $p_user_id = null ) { $t_platforms_array = profile_get_field_all_for_user( 'platform', $p_user_id ); foreach( $t_platforms_array as $t_platform_unescaped ) { $t_platform = string_attribute( $t_platform_unescaped ); echo '<option value="' . $t_platform . '"'; check_selected( $p_platform, $t_platform_unescaped ); echo '>' . $t_platform . '</option>'; } } /** * Print the option list for OSes accessible for the specified user. * @param string $p_os The current operating system value. * @param integer $p_user_id A user identifier. * @return void */ function print_os_option_list( $p_os, $p_user_id = null ) { $t_os_array = profile_get_field_all_for_user( 'os', $p_user_id ); foreach( $t_os_array as $t_os_unescaped ) { $t_os = string_attribute( $t_os_unescaped ); echo '<option value="' . $t_os . '"'; check_selected( $p_os, $t_os_unescaped ); echo '>' . $t_os . '</option>'; } } /** * Print the option list for os_build accessible for the specified user. * @param string $p_os_build The current operating system build value. * @param integer $p_user_id A user identifier. * @return void */ function print_os_build_option_list( $p_os_build, $p_user_id = null ) { $t_os_build_array = profile_get_field_all_for_user( 'os_build', $p_user_id ); foreach( $t_os_build_array as $t_os_build_unescaped ) { $t_os_build = string_attribute( $t_os_build_unescaped ); echo '<option value="' . $t_os_build . '"'; check_selected( $p_os_build, $t_os_build_unescaped ); echo '>' . $t_os_build . '</option>'; } } /** * Print the option list for versions * @param string $p_version The currently selected version. * @param integer $p_project_id Project id, otherwise current project will be used. * @param integer $p_released Null to get all, 1: only released, 0: only future versions. * @param boolean $p_leading_blank Allow selection of no version. * @param boolean $p_with_subs Whether to include sub-projects. * @return void */ function print_version_option_list( $p_version = '', $p_project_id = null, $p_released = null, $p_leading_blank = true, $p_with_subs = false ) { if( null === $p_project_id ) { $c_project_id = helper_get_current_project(); } else { $c_project_id = (int)$p_project_id; } if( $p_with_subs ) { $t_versions = version_get_all_rows_with_subs( $c_project_id, $p_released, null ); } else { $t_versions = version_get_all_rows( $c_project_id, $p_released, null ); } # Ensure the selected version (if specified) is included in the list # Note: Filter API specifies selected versions as an array if( !is_array( $p_version ) ) { if( !empty( $p_version ) ) { $t_version_id = version_get_id( $p_version, $c_project_id ); if( $t_version_id !== false ) { $t_versions[] = version_cache_row( $t_version_id ); } } } if( $p_leading_blank ) { echo '<option value=""></option>'; } $t_listed = array(); $t_max_length = config_get( 'max_dropdown_length' ); foreach ($t_versions as $bsh_key => $bsh_row) { $bsh_version[$bsh_key] = string_attribute( prepare_version_string( $c_project_id, $bsh_row['id'] ) ); } array_multisort($bsh_version, SORT_DESC, SORT_STRING, $t_versions); foreach( $t_versions as $t_version ) { # If the current version is obsolete, and current version not equal to $p_version, # then skip it. if( ( (int)$t_version['obsolete'] ) == 1 ) { if( $t_version['version'] != $p_version ) { continue; } } $t_version_version = string_attribute( $t_version['version'] ); if( !in_array( $t_version_version, $t_listed, true ) ) { $t_listed[] = $t_version_version; echo '<option value="' . $t_version_version . '"'; check_selected( $p_version, $t_version['version'] ); $t_version_string = string_attribute( prepare_version_string( $c_project_id, $t_version['id'] ) ); echo '>', string_shorten( $t_version_string, $t_max_length ), '</option>'; } } } /** * print build option list * @param string $p_build The current build value. * @return void */ function print_build_option_list( $p_build = '' ) { $t_overall_build_arr = array(); $t_project_id = helper_get_current_project(); $t_project_where = helper_project_specific_where( $t_project_id ); # Get the "found in" build list $t_query = 'SELECT DISTINCT build FROM {bug} WHERE ' . $t_project_where . ' ORDER BY build DESC'; $t_result = db_query( $t_query ); while( $t_row = db_fetch_array( $t_result ) ) { $t_overall_build_arr[] = $t_row['build']; } $t_max_length = config_get( 'max_dropdown_length' ); foreach( $t_overall_build_arr as $t_build_unescaped ) { $t_build = string_attribute( $t_build_unescaped ); echo '<option value="' . $t_build . '"'; check_selected( $p_build, $t_build_unescaped ); echo '>' . string_shorten( $t_build, $t_max_length ) . '</option>'; } } /** * select the proper enumeration values based on the input parameter * Current value may be an integer, or an array of integers. * @param string $p_enum_name Name of enumeration (eg: status). * @param integer|array $p_val The current value(s) * @return void */ function print_enum_string_option_list( $p_enum_name, $p_val = 0 ) { $t_config_var_name = $p_enum_name . '_enum_string'; $t_config_var_value = config_get( $t_config_var_name ); if( is_array( $p_val ) ) { $t_val = $p_val; } else { $t_val = (int)$p_val; } $t_enum_values = MantisEnum::getValues( $t_config_var_value ); foreach ( $t_enum_values as $t_key ) { $t_elem2 = get_enum_element( $p_enum_name, $t_key ); echo '<option value="' . $t_key . '"'; check_selected( $t_val, $t_key ); echo '>' . string_html_specialchars( $t_elem2 ) . '</option>'; } } /** * Select the proper enumeration values for status based on workflow * or the input parameter if workflows are not used * @param integer $p_user_auth A user identifier. * @param integer $p_current_value The current value. * @param boolean $p_show_current Whether to show the current status. * @param boolean $p_add_close Whether to add close option. * @param integer $p_project_id A project identifier. * @return array */ function get_status_option_list( $p_user_auth = 0, $p_current_value = 0, $p_show_current = true, $p_add_close = false, $p_project_id = ALL_PROJECTS ) { $t_config_var_value = config_get( 'status_enum_string', null, null, $p_project_id ); $t_enum_workflow = config_get( 'status_enum_workflow', null, null, $p_project_id ); if( count( $t_enum_workflow ) < 1 || !MantisEnum::hasValue( $t_config_var_value, $p_current_value ) ) { # workflow not defined, use default enumeration $t_enum_values = MantisEnum::getValues( $t_config_var_value ); } else { # workflow defined - find allowed states if( isset( $t_enum_workflow[$p_current_value] ) ) { $t_enum_values = MantisEnum::getValues( $t_enum_workflow[$p_current_value] ); } else { # workflow was not set for this status, this shouldn't happen # caller should be able to handle empty list $t_enum_values = array(); } } $t_enum_list = array(); foreach ( $t_enum_values as $t_enum_value ) { if( ( $p_show_current || $p_current_value != $t_enum_value ) && access_compare_level( $p_user_auth, access_get_status_threshold( $t_enum_value, $p_project_id ) ) ) { $t_enum_list[$t_enum_value] = get_enum_element( 'status', $t_enum_value ); } } if( $p_show_current ) { $t_enum_list[$p_current_value] = get_enum_element( 'status', $p_current_value ); } if( $p_add_close && access_compare_level( $p_current_value, config_get( 'bug_resolved_status_threshold', null, null, $p_project_id ) ) ) { $t_closed = config_get( 'bug_closed_status_threshold', null, null, $p_project_id ); if( $p_show_current || $p_current_value != $t_closed ) { $t_enum_list[$t_closed] = get_enum_element( 'status', $t_closed ); } } return $t_enum_list; } /** * print the status option list for the bug_update pages * @param string $p_select_label The id/name html attribute of the select box. * @param integer $p_current_value The current value. * @param boolean $p_allow_close Whether to allow close. * @param integer $p_project_id A project identifier. * @return void */ function print_status_option_list( $p_select_label, $p_current_value = 0, $p_allow_close = false, $p_project_id = ALL_PROJECTS ) { $t_current_auth = access_get_project_level( $p_project_id ); $t_enum_list = get_status_option_list( $t_current_auth, $p_current_value, true, $p_allow_close, $p_project_id ); if( count( $t_enum_list ) > 1 ) { # resort the list into ascending order ksort( $t_enum_list ); reset( $t_enum_list ); echo '<select ' . helper_get_tab_index() . ' id="' . $p_select_label . '" name="' . $p_select_label . '">'; foreach( $t_enum_list as $t_key => $t_val ) { echo '<option value="' . $t_key . '"'; check_selected( $t_key, $p_current_value ); echo '>' . string_html_specialchars( $t_val ) . '</option>'; } echo '</select>'; } else if( count( $t_enum_list ) == 1 ) { echo array_pop( $t_enum_list ); } else { echo MantisEnum::getLabel( lang_get( 'status_enum_string' ), $p_current_value ); } } /** * prints the list of a project's users * if no project is specified uses the current project * @param integer $p_project_id A project identifier. * @return void */ function print_project_user_option_list( $p_project_id = null ) { print_user_option_list( 0, $p_project_id ); } /** * prints the list of access levels that are less than or equal to the access level of the * logged in user. This is used when adding users to projects * @param integer $p_val The current value. * @param integer $p_project_id A project identifier. * @return void */ function print_project_access_levels_option_list( $p_val, $p_project_id = null ) { $t_current_user_access_level = access_get_project_level( $p_project_id ); $t_access_levels_enum_string = config_get( 'access_levels_enum_string' ); $t_enum_values = MantisEnum::getValues( $t_access_levels_enum_string ); foreach ( $t_enum_values as $t_enum_value ) { # a user must not be able to assign another user an access level that is higher than theirs. if( $t_enum_value > $t_current_user_access_level ) { continue; } $t_access_level = get_enum_element( 'access_levels', $t_enum_value ); echo '<option value="' . $t_enum_value . '"'; check_selected( $p_val, $t_enum_value ); echo '>' . string_html_specialchars( $t_access_level ) . '</option>'; } } /** * Print option list of available language choices * @param string $p_language The current language. * @return void */ function print_language_option_list( $p_language ) { $t_arr = config_get( 'language_choices_arr' ); $t_enum_count = count( $t_arr ); for( $i = 0;$i < $t_enum_count;$i++ ) { $t_language = string_attribute( $t_arr[$i] ); echo '<option value="' . $t_language . '"'; check_selected( $t_language, $p_language ); echo '>' . $t_language . '</option>'; } } /** * Print a dropdown list of all bug actions available to a user for a specified * set of projects. * @param array $p_project_ids An array containing one or more project IDs. * @return void */ function print_all_bug_action_option_list( array $p_project_ids = null ) { $t_commands = bug_group_action_get_commands( $p_project_ids ); while( list( $t_action_id, $t_action_label ) = each( $t_commands ) ) { echo '<option value="' . $t_action_id . '">' . $t_action_label . '</option>'; } } /** * list of users that are NOT in the specified project and that are enabled * if no project is specified use the current project * also exclude any administrators * @param integer $p_project_id A project identifier. * @return void */ function print_project_user_list_option_list( $p_project_id = null ) { $t_users = user_get_unassigned_by_project_id( $p_project_id ); foreach( $t_users as $t_id=>$t_name ) { echo '<option value="' . $t_id . '">' . $t_name . '</option>'; } } /** * list of projects that a user is NOT in * @param integer $p_user_id An user identifier. * @return void */ function print_project_user_list_option_list2( $p_user_id ) { db_param_push(); $t_query = 'SELECT DISTINCT p.id, p.name FROM {project} p LEFT JOIN {project_user_list} u ON p.id=u.project_id AND u.user_id=' . db_param() . ' WHERE p.enabled = ' . db_param() . ' AND u.user_id IS NULL ORDER BY p.name'; $t_result = db_query( $t_query, array( (int)$p_user_id, true ) ); $t_category_count = db_num_rows( $t_result ); while( $t_row = db_fetch_array( $t_result ) ) { $t_project_name = string_attribute( $t_row['name'] ); $t_user_id = $t_row['id']; echo '<option value="' . $t_user_id . '">' . $t_project_name . '</option>'; } } /** * list of projects that a user is in * @param integer $p_user_id An user identifier. * @param boolean $p_include_remove_link Whether to display remove link. * @return void */ function print_project_user_list( $p_user_id, $p_include_remove_link = true ) { $t_projects = user_get_assigned_projects( $p_user_id ); foreach( $t_projects as $t_project_id=>$t_project ) { $t_project_name = string_attribute( $t_project['name'] ); $t_view_state = $t_project['view_state']; $t_access_level = $t_project['access_level']; $t_access_level = get_enum_element( 'access_levels', $t_access_level ); $t_view_state = get_enum_element( 'project_view_state', $t_view_state ); echo $t_project_name . ' [' . $t_access_level . '] (' . $t_view_state . ')'; if( $p_include_remove_link && access_has_project_level( config_get( 'project_user_threshold' ), $t_project_id ) ) { html_button( 'manage_user_proj_delete.php', lang_get( 'remove_link' ), array( 'project_id' => $t_project_id, 'user_id' => $p_user_id ) ); } echo '<br />'; } } /** * List of projects with which the specified field id is linked. * For every project, the project name is listed and then the list of custom * fields linked in order with their sequence numbers. The specified field * is always highlighted in italics and project names in bold. * * @param integer $p_field_id The field to list the projects associated with. * @return void */ function print_custom_field_projects_list( $p_field_id ) { $c_field_id = (integer)$p_field_id; $t_project_ids = custom_field_get_project_ids( $p_field_id ); $t_security_token = form_security_param( 'manage_proj_custom_field_remove' ); foreach( $t_project_ids as $t_project_id ) { $t_project_name = project_get_field( $t_project_id, 'name' ); $t_sequence = custom_field_get_sequence( $p_field_id, $t_project_id ); echo '<strong>', string_display_line( $t_project_name ), '</strong>: '; print_bracket_link( 'manage_proj_custom_field_remove.php?field_id=' . $c_field_id . '&project_id=' . $t_project_id . '&return=custom_field' . $t_security_token, lang_get( 'remove_link' ) ); echo '<br />- '; $t_linked_field_ids = custom_field_get_linked_ids( $t_project_id ); $t_first = true; foreach( $t_linked_field_ids as $t_current_field_id ) { if( $t_first ) { $t_first = false; } else { echo ', '; } if( $t_current_field_id == $p_field_id ) { echo '<em>'; } echo string_display_line( custom_field_get_field( $t_current_field_id, 'name' ) ); echo ' (', custom_field_get_sequence( $t_current_field_id, $t_project_id ), ')'; if( $t_current_field_id == $p_field_id ) { echo '</em>'; } } echo '<br /><br />'; } } /** * List of priorities that can be assigned to a plugin. * @param integer $p_priority Current priority. * @return void */ function print_plugin_priority_list( $p_priority ) { if( $p_priority < 1 && $p_priority > 5 ) { echo '<option value="', $p_priority, '" selected="selected">', $p_priority, '</option>'; } for( $i = 5;$i >= 1;$i-- ) { echo '<option value="', $i, '" ', check_selected( $p_priority, $i ), ' >', $i, '</option>'; } } /** * prints a link to VIEW a bug given an ID * account for the user preference and site override * @param integer $p_bug_id A bug identifier. * @param boolean $p_detail_info Detail info to display with the link. * @return void */ function print_bug_link( $p_bug_id, $p_detail_info = true ) { echo string_get_bug_view_link( $p_bug_id, $p_detail_info ); } /** * formats the priority given the status * shows the priority in BOLD if the bug is NOT closed and is of significant priority * @param BugData $p_bug Bug Object. * @return void */ function print_formatted_priority_string( BugData $p_bug ) { $t_pri_str = get_enum_element( 'priority', $p_bug->priority, auth_get_current_user_id(), $p_bug->project_id ); $t_priority_threshold = config_get( 'priority_significant_threshold' ); if( $t_priority_threshold >= 0 && $p_bug->priority >= $t_priority_threshold && $p_bug->status < config_get( 'bug_closed_status_threshold' ) ) { echo '<span class="bold">' . $t_pri_str . '</span>'; } else { echo $t_pri_str; } } /** * formats the severity given the status * shows the severity in BOLD if the bug is NOT closed and is of significant severity * @param BugData $p_bug Bug Object. * @return void */ function print_formatted_severity_string( BugData $p_bug ) { $t_sev_str = get_enum_element( 'severity', $p_bug->severity, auth_get_current_user_id(), $p_bug->project_id ); $t_severity_threshold = config_get( 'severity_significant_threshold' ); if( $t_severity_threshold >= 0 && $p_bug->severity >= $t_severity_threshold && $p_bug->status < config_get( 'bug_closed_status_threshold' ) ) { echo '<span class="bold">' . $t_sev_str . '</span>'; } else { echo $t_sev_str; } } /** * Print view bug sort link * @todo params should be in same order as print_manage_user_sort_link * @param string $p_string The displayed text of the link. * @param string $p_sort_field The field to sort. * @param string $p_sort The field to sort by. * @param string $p_dir The sort direction - either ASC or DESC. * @param integer $p_columns_target See COLUMNS_TARGET_* in constant_inc.php. * @return void */ function print_view_bug_sort_link( $p_string, $p_sort_field, $p_sort, $p_dir, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) { if( $p_columns_target == COLUMNS_TARGET_PRINT_PAGE ) { if( $p_sort_field == $p_sort ) { # We toggle between ASC and DESC if the user clicks the same sort order if( 'ASC' == $p_dir ) { $p_dir = 'DESC'; } else { $p_dir = 'ASC'; } } else { # Otherwise always start with ascending $p_dir = 'ASC'; } $t_sort_field = rawurlencode( $p_sort_field ); print_link( 'view_all_set.php?sort=' . $t_sort_field . '&dir=' . $p_dir . '&type=2&print=1', $p_string ); } else if( $p_columns_target == COLUMNS_TARGET_VIEW_PAGE ) { if( $p_sort_field == $p_sort ) { # we toggle between ASC and DESC if the user clicks the same sort order if( 'ASC' == $p_dir ) { $p_dir = 'DESC'; } else { $p_dir = 'ASC'; } } else { # Otherwise always start with ascending $p_dir = 'ASC'; } $t_sort_field = rawurlencode( $p_sort_field ); print_link( 'view_all_set.php?sort=' . $t_sort_field . '&dir=' . $p_dir . '&type=2', $p_string ); } else { echo $p_string; } } /** * Print manage user sort link * @param string $p_page The page within mantis to link to. * @param string $p_string The displayed text of the link. * @param string $p_field The field to sort. * @param string $p_dir The sort direction - either ASC or DESC. * @param string $p_sort_by The field to sort by. * @param integer $p_hide_inactive Whether to hide inactive users. * @param integer $p_filter The filter to use. * @param integer $p_show_disabled Whether to show disabled users. * @return void */ function print_manage_user_sort_link( $p_page, $p_string, $p_field, $p_dir, $p_sort_by, $p_hide_inactive = 0, $p_filter = ALL, $p_show_disabled = 0 ) { if( $p_sort_by == $p_field ) { # If this is the selected field flip the order if( 'ASC' == $p_dir || ASCENDING == $p_dir ) { $t_dir = 'DESC'; } else { $t_dir = 'ASC'; } } else { # Otherwise always start with ASCending $t_dir = 'ASC'; } $t_field = rawurlencode( $p_field ); print_link( $p_page . '?sort=' . $t_field . '&dir=' . $t_dir . '&save=1&hideinactive=' . $p_hide_inactive . '&showdisabled=' . $p_show_disabled . '&filter=' . $p_filter, $p_string ); } /** * Print manage project sort link * @param string $p_page The page within mantis to link to. * @param string $p_string The displayed text of the link. * @param string $p_field The field to sort. * @param string $p_dir The sort direction - either ASC or DESC. * @param string $p_sort_by The field to sort by. * @return void */ function print_manage_project_sort_link( $p_page, $p_string, $p_field, $p_dir, $p_sort_by ) { if( $p_sort_by == $p_field ) { # If this is the selected field flip the order if( 'ASC' == $p_dir || ASCENDING == $p_dir ) { $t_dir = 'DESC'; } else { $t_dir = 'ASC'; } } else { # Otherwise always start with ASCending $t_dir = 'ASC'; } $t_field = rawurlencode( $p_field ); print_link( $p_page . '?sort=' . $t_field . '&dir=' . $t_dir, $p_string ); } /** * Print a button which presents a standalone form. * If $p_security_token is OFF, the button's form will not contain a security * field; this is useful when form does not result in modifications (CSRF is not * needed). If otherwise specified (i.e. not null), the parameter must contain * a valid security token, previously generated by form_security_token(). * Use this to avoid performance issues when loading pages having many calls to * this function, such as adm_config_report.php. * @param string $p_action_page The action page. * @param string $p_label The button label. * @param array $p_args_to_post Associative array of arguments to be posted, with * arg name => value, defaults to null (no args). * @param mixed $p_security_token Optional; null (default), OFF or security token string. * @see form_security_token() * @return void */ function print_button( $p_action_page, $p_label, array $p_args_to_post = null, $p_security_token = null ) { $t_form_name = explode( '.php', $p_action_page, 2 ); # TODO: ensure all uses of print_button supply arguments via $p_args_to_post (POST) # instead of via $p_action_page (GET). Then only add the CSRF form token if # arguments are being sent via the POST method. echo '<form method="post" action="', htmlspecialchars( $p_action_page ), '" class="action-button">'; echo '<fieldset>'; if( $p_security_token !== OFF ) { echo form_security_field( $t_form_name[0], $p_security_token ); } echo '<input type="submit" class="button-small" value="', $p_label, '" />'; if( $p_args_to_post !== null ) { foreach( $p_args_to_post as $t_var => $t_value ) { echo '<input type="hidden" name="' . $t_var . '" value="' . htmlentities( $t_value ) . '" />'; } } echo '</fieldset>'; echo '</form>'; } /** * print brackets around a pre-prepared link (i.e. '<a href' html tag). * @param string $p_link The URL to link to. * @return void */ function print_bracket_link_prepared( $p_link ) { echo '<span class="bracket-link">[ ' . $p_link . ' ]</span> '; } /** * print the bracketed links used near the top * if the $p_link is blank then the text is printed but no link is created * if $p_new_window is true, link will open in a new window, default false. * @param string $p_link The URL to link to. * @param string $p_url_text The text to display. * @param boolean $p_new_window Whether to open in a new window. * @param string $p_class CSS class to use with the link. * @return void */ function print_bracket_link( $p_link, $p_url_text, $p_new_window = false, $p_class = '' ) { echo '<span class="bracket-link'; if( $p_class !== '' ) { echo ' bracket-link-',$p_class; # prefix on a container allows styling of whole link, including brackets } echo '">[ '; print_link( $p_link, $p_url_text, $p_new_window, $p_class ); echo ' ]</span> '; } /** * print a HTML link * @param string $p_link The page URL. * @param string $p_url_text The displayed text for the link. * @param boolean $p_new_window Whether to open in a new window. * @param string $p_class The CSS class of the link. * @return void */ function print_link( $p_link, $p_url_text, $p_new_window = false, $p_class = '' ) { if( is_blank( $p_link ) ) { echo $p_url_text; } else { $t_link = htmlspecialchars( $p_link ); if( $p_new_window === true ) { echo '<a class="new-window ' . $p_class . '" href="' . $t_link . '" target="_blank">' . $p_url_text . '</a>'; } else { if( $p_class !== '' ) { echo '<a class="' . $p_class . '" href="' . $t_link . '">' . $p_url_text . '</a>'; } else { echo '<a href="' . $t_link . '">' . $p_url_text . '</a>'; } } } } /** * print a HTML page link * @param string $p_page_url The Page URL. * @param string $p_text The displayed text for the link. * @param integer $p_page_no The page number to link to. * @param integer $p_page_cur The current page number. * @param integer $p_temp_filter_id Temporary filter id. * @return void */ function print_page_link( $p_page_url, $p_text = '', $p_page_no = 0, $p_page_cur = 0, $p_temp_filter_id = 0 ) { if( is_blank( $p_text ) ) { $p_text = $p_page_no; } if( ( 0 < $p_page_no ) && ( $p_page_no != $p_page_cur ) ) { $t_delimiter = ( strpos( $p_page_url, '?' ) ? '&' : '?' ); if( $p_temp_filter_id !== 0 ) { print_link( $p_page_url . $t_delimiter . 'filter=' . $p_temp_filter_id . '&page_number=' . $p_page_no, $p_text ); } else { print_link( $p_page_url . $t_delimiter . 'page_number=' . $p_page_no, $p_text ); } } else { echo $p_text; } } /** * print a list of page number links (eg [1 2 3]) * @param string $p_page The Page URL. * @param integer $p_start The first page number. * @param integer $p_end The last page number. * @param integer $p_current The current page number. * @param integer $p_temp_filter_id Temporary filter id. * @return void */ function print_page_links( $p_page, $p_start, $p_end, $p_current, $p_temp_filter_id = 0 ) { $t_items = array(); # Check if we have more than one page, # otherwise return without doing anything. if( $p_end - $p_start < 1 ) { return; } # Get localized strings $t_first = lang_get( 'first' ); $t_last = lang_get( 'last' ); $t_prev = lang_get( 'prev' ); $t_next = lang_get( 'next' ); $t_page_links = 10; print( '[ ' ); # First and previous links print_page_link( $p_page, $t_first, 1, $p_current, $p_temp_filter_id ); echo ' '; print_page_link( $p_page, $t_prev, $p_current - 1, $p_current, $p_temp_filter_id ); echo ' '; # Page numbers ... $t_first_page = max( $p_start, $p_current - $t_page_links / 2 ); $t_first_page = min( $t_first_page, $p_end - $t_page_links ); $t_first_page = max( $t_first_page, $p_start ); if( $t_first_page > 1 ) { print( ' ... ' ); } $t_last_page = $t_first_page + $t_page_links; $t_last_page = min( $t_last_page, $p_end ); for( $i = $t_first_page;$i <= $t_last_page;$i++ ) { if( $i == $p_current ) { array_push( $t_items, $i ); } else { $t_delimiter = ( strpos( $p_page, '?' ) ? '&' : '?' ) ; if( $p_temp_filter_id !== 0 ) { array_push( $t_items, '<a href="' . $p_page . $t_delimiter . 'filter=' . $p_temp_filter_id . '&page_number=' . $i . '">' . $i . '</a>' ); } else { array_push( $t_items, '<a href="' . $p_page . $t_delimiter . 'page_number=' . $i . '">' . $i . '</a>' ); } } } echo implode( ' ', $t_items ); if( $t_last_page < $p_end ) { print( ' ... ' ); } # Next and Last links echo ' '; if( $p_current < $p_end ) { print_page_link( $p_page, $t_next, $p_current + 1, $p_current, $p_temp_filter_id ); } else { print_page_link( $p_page, $t_next, null, null, $p_temp_filter_id ); } echo ' '; print_page_link( $p_page, $t_last, $p_end, $p_current, $p_temp_filter_id ); print( ' ]' ); } /** * print a mailto: href link * * @param string $p_email Email Address. * @param string $p_text Link text to display to user. * @return void */ function print_email_link( $p_email, $p_text ) { echo get_email_link( $p_email, $p_text ); } /** * return the mailto: href string link instead of printing it * * @param string $p_email Email Address. * @param string $p_text Link text to display to user. * @return string */ function get_email_link( $p_email, $p_text ) { return prepare_email_link( $p_email, $p_text ); } /** * print a mailto: href link with subject * * @param string $p_email Email Address. * @param string $p_text Link text to display to user. * @param string $p_bug_id The bug identifier. * @return void */ function print_email_link_with_subject( $p_email, $p_text, $p_bug_id ) { $t_bug = bug_get( $p_bug_id, true ); if( !access_has_project_level( config_get( 'show_user_email_threshold', null, null, $t_bug->project_id ), $t_bug->project_id ) ) { echo $p_text; return; } $t_subject = email_build_subject( $p_bug_id ); echo get_email_link_with_subject( $p_email, $p_text, $t_subject ); } /** * return the mailto: href string link instead of printing it * add subject line * * @param string $p_email Email Address. * @param string $p_text Link text to display to user. * @param string $p_subject Email subject line. * @return string */ function get_email_link_with_subject( $p_email, $p_text, $p_subject ) { # If we apply string_url() to the whole mailto: link then the @ # gets turned into a %40 and you can't right click in browsers to # do Copy Email Address. If we don't apply string_url() to the # subject text then an ampersand (for example) will truncate the text $t_subject = string_url( $p_subject ); $t_email = string_url( $p_email ); $t_mailto = string_attribute( 'mailto:' . $t_email . '?subject=' . $t_subject ); $t_text = string_display( $p_text ); return '<a class="user" href="' . $t_mailto . '">' . $t_text . '</a>'; } /** * Print a hidden input for each name=>value pair in the array * * If a value is an array an input will be created for each item with a name * that ends with [] * The names and values are passed through htmlspecialchars() before being displayed * * @param array $p_assoc_array Array of Name/Value pairs for html input tags. * @return void */ function print_hidden_inputs( array $p_assoc_array ) { foreach( $p_assoc_array as $t_key => $t_val ) { print_hidden_input( $t_key, $t_val ); } } /** * Print hidden html input tag <input type=hidden> * * @param string $p_field_key Name parameter. * @param string $p_field_val Value parameter. * @return void */ function print_hidden_input( $p_field_key, $p_field_val ) { if( is_array( $p_field_val ) ) { foreach( $p_field_val as $t_key => $t_value ) { if( is_array( $t_value ) ) { $t_key = string_html_entities( $t_key ); $t_field_key = $p_field_key . '[' . $t_key . ']'; print_hidden_input( $t_field_key, $t_value ); } else { $t_field_key = $p_field_key . '[' . $t_key . ']'; print_hidden_input( $t_field_key, $t_value ); } } } else { $t_key = string_html_entities( $p_field_key ); $t_val = string_html_entities( $p_field_val ); echo '<input type="hidden" name="' . $t_key . '" value="' . $t_val . '" />' . "\n"; } } /** * This prints the little [?] link for user help * @param string $p_a_name The anchor to use when accessing the documentation. * @return void */ function print_documentation_link( $p_a_name = '' ) { echo lang_get( $p_a_name ); # @todo Disable documentation links for now. May be re-enabled if linked to new manual. # echo "<a href=\"doc/documentation.html#$p_a_name\" target=\"_info\">[?]</a>"; } /** * prints the sign up link * @return void */ function print_signup_link() { if( ( ON == config_get_global( 'allow_signup' ) ) && ( LDAP != config_get_global( 'login_method' ) ) && ( ON == config_get( 'enable_email_notification' ) ) ) { print_bracket_link( 'signup_page.php', lang_get( 'signup_link' ) ); } } /** * prints the login link * @return void */ function print_login_link() { print_bracket_link( 'login_page.php', lang_get( 'login_title' ) ); } /** * prints the lost password link * @return void */ function print_lost_password_link() { # lost password feature disabled or reset password via email disabled -> stop here! if( ( LDAP != config_get_global( 'login_method' ) ) && ( ON == config_get( 'lost_password_feature' ) ) && ( ON == config_get( 'send_reset_password' ) ) && ( ON == config_get( 'enable_email_notification' ) ) ) { print_bracket_link( 'lost_pwd_page.php', lang_get( 'lost_password_link' ) ); } } /** * Get icon corresponding to the specified filename * * @param string $p_filename Filename for which to retrieve icon link. * @return void */ function print_file_icon( $p_filename ) { $t_icon = file_get_icon_url( $p_filename ); echo '<img src="' . string_attribute( $t_icon['url'] ) . '" alt="' . string_attribute( $t_icon['alt'] ) . ' file icon" width="16" height="16" />'; } /** * Prints an RSS image that is hyperlinked to an RSS feed. * * @param string $p_feed_url URI to an RSS feed. * @param string $p_title Title to use for hyperlink. * @return void */ function print_rss( $p_feed_url, $p_title = '' ) { $t_path = config_get( 'path' ); echo '<a class="rss" rel="alternate" href="', htmlspecialchars( $p_feed_url ), '" title="', $p_title, '"><img src="', $t_path, '/images/', 'rss.png" width="16" height="16" alt="', $p_title, '" /></a>'; } /** * Prints the recently visited issues. * @return void */ function print_recently_visited() { $t_ids = last_visited_get_array(); if( count( $t_ids ) == 0 ) { return; } echo '<div class="recently-visited">' . lang_get( 'recently_visited' ) . ': '; $t_first = true; foreach( $t_ids as $t_id ) { if( !$t_first ) { echo ', '; } else { $t_first = false; } echo string_get_bug_view_link( $t_id ); } echo '</div>'; } /** * print a drop down box from input array * @param array $p_control_array Array of elements in drop down list (name, description). * @param string $p_control_name Name attribute of <select> box. * @param string|array $p_match Either a string or an array of selected values. * @param boolean $p_add_any Whether to display an '[any]' option in the drop down. * @param boolean $p_multiple Whether drop down list allows multiple values to be selected. * @return string */ function get_dropdown( array $p_control_array, $p_control_name, $p_match = '', $p_add_any = false, $p_multiple = false ) { if( $p_multiple ) { $t_size = ' size="5"'; $t_multiple = ' multiple="multiple"'; } else { $t_size = ''; $t_multiple = ''; } $t_info = sprintf( '<select %s name="%s" id="%s"%s>', $t_multiple, $p_control_name, $p_control_name, $t_size ); if( $p_add_any ) { array_unshift_assoc( $p_control_array, META_FILTER_ANY, lang_trans( '[any]' ) ); } while( list( $t_name, $t_desc ) = each( $p_control_array ) ) { $t_sel = ''; if( is_array( $p_match ) ) { if( in_array( $t_name, array_values( $p_match ) ) || in_array( $t_desc, array_values( $p_match ) ) ) { $t_sel = ' selected="selected"'; } } else { if( ( $t_name === $p_match ) || ( $t_desc === $p_match ) ) { $t_sel = ' selected="selected"'; } } $t_info .= sprintf( '<option%s value="%s">%s</option>', $t_sel, $t_name, $t_desc ); } $t_info .= "</select>\n"; return $t_info; } /** * Prints the list of visible attachments belonging to a given bug. * @param integer $p_bug_id ID of the bug to print attachments list for. * @return void */ function print_bug_attachments_list( $p_bug_id ) { $t_attachments = file_get_visible_attachments( $p_bug_id ); echo "\n<ul>"; foreach ( $t_attachments as $t_attachment ) { echo "\n<li>"; print_bug_attachment( $t_attachment ); echo "\n</li>"; } echo "\n</ul>"; } /** * Prints information about a single attachment including download link, file * size, upload timestamp and an expandable preview for text and image file * types. * If $p_security_token is null, a token will be generated with form_security_token(). * If otherwise specified (i.e. not null), the parameter must contain * a valid security token, previously generated by form_security_token(). * Use this to avoid performance issues when loading pages having many calls to * this function, such as print_bug_attachments_list(). * @param array $p_attachment An attachment array from within the array returned by the file_get_visible_attachments() function. * @param mixed $p_security_token Optional; null (default) or security token string. * @see form_security_token() * @return void */ function print_bug_attachment( array $p_attachment, $p_security_token = null ) { $t_show_attachment_preview = $p_attachment['preview'] && $p_attachment['exists'] && ( $p_attachment['type'] == 'text' || $p_attachment['type'] == 'image' ); if( $t_show_attachment_preview ) { $t_collapse_id = 'attachment_preview_' . $p_attachment['id']; global $g_collapse_cache_token; $g_collapse_cache_token[$t_collapse_id] = false; collapse_open( $t_collapse_id ); } # The same token is used for both links in the collapse section if( null === $p_security_token ) { $p_security_token = form_security_token( 'bug_file_delete' ); } print_bug_attachment_header( $p_attachment, $p_security_token ); if( $t_show_attachment_preview ) { echo lang_get( 'word_separator' ); collapse_icon( $t_collapse_id ); if( $p_attachment['type'] == 'text' ) { print_bug_attachment_preview_text( $p_attachment ); } else if( $p_attachment['type'] === 'image' ) { print_bug_attachment_preview_image( $p_attachment ); } collapse_closed( $t_collapse_id ); print_bug_attachment_header( $p_attachment, $p_security_token ); echo lang_get( 'word_separator' ); collapse_icon( $t_collapse_id ); collapse_end( $t_collapse_id ); } } /** * Prints a single textual line of information about an attachment including download link, file * size and upload timestamp. * If $p_security_token is null, a token will be generated with form_security_token(). * If otherwise specified (i.e. not null), the parameter must contain * a valid security token, previously generated by form_security_token(). * Use this to avoid performance issues when loading pages having many calls to * this function, such as print_bug_attachments_list(). * @param array $p_attachment An attachment array from within the array returned by the file_get_visible_attachments() function. * @param mixed $p_security_token Optional; null (default) or security token string. * @see form_security_token() * @return void */ function print_bug_attachment_header( array $p_attachment, $p_security_token = null ) { echo "\n"; if( $p_attachment['exists'] ) { if( $p_attachment['can_download'] ) { echo '<a href="' . string_attribute( $p_attachment['download_url'] ) . '">'; } print_file_icon( $p_attachment['display_name'] ); if( $p_attachment['can_download'] ) { echo '</a>'; } echo lang_get( 'word_separator' ); if( $p_attachment['can_download'] ) { echo '<a href="' . string_attribute( $p_attachment['download_url'] ) . '">'; } echo string_display_line( $p_attachment['display_name'] ); if( $p_attachment['can_download'] ) { echo '</a>'; } echo lang_get( 'word_separator' ) . '(' . number_format( $p_attachment['size'] ) . lang_get( 'word_separator' ) . lang_get( 'bytes' ) . ')'; echo lang_get( 'word_separator' ) . '<span class="italic">' . date( config_get( 'normal_date_format' ), $p_attachment['date_added'] ) . '</span>'; event_signal( 'EVENT_VIEW_BUG_ATTACHMENT', array( $p_attachment ) ); } else { print_file_icon( $p_attachment['display_name'] ); echo lang_get( 'word_separator' ) . '<span class="strike">' . string_display_line( $p_attachment['display_name'] ) . '</span>' . lang_get( 'word_separator' ) . '(' . lang_get( 'attachment_missing' ) . ')'; } if( $p_attachment['can_delete'] ) { echo lang_get( 'word_separator' ) . '['; print_link( 'bug_file_delete.php?file_id=' . $p_attachment['id'] . form_security_param( 'bug_file_delete', $p_security_token ), lang_get( 'delete_link' ), false, 'small' ); echo ']'; } } /** * Prints the preview of a text file attachment. * @param array $p_attachment An attachment array from within the array returned by the file_get_visible_attachments() function. * @return void */ function print_bug_attachment_preview_text( array $p_attachment ) { if( !$p_attachment['exists'] ) { return; } echo "\n<pre class=\"bug-attachment-preview-text\">"; switch( config_get( 'file_upload_method' ) ) { case DISK: if( file_exists( $p_attachment['diskfile'] ) ) { $t_content = file_get_contents( $p_attachment['diskfile'] ); } break; case DATABASE: db_param_push(); $t_query = 'SELECT * FROM {bug_file} WHERE id=' . db_param(); $t_result = db_query( $t_query, array( (int)$p_attachment['id'] ) ); $t_row = db_fetch_array( $t_result ); $t_content = $t_row['content']; break; default: trigger_error( ERROR_GENERIC, ERROR ); } echo htmlspecialchars( $t_content ); echo '</pre>'; } /** * Prints the preview of an image file attachment. * @param array $p_attachment An attachment array from within the array returned by the file_get_visible_attachments() function. * @return void */ function print_bug_attachment_preview_image( array $p_attachment ) { $t_preview_style = 'border: 0;'; $t_max_width = config_get( 'preview_max_width' ); if( $t_max_width > 0 ) { $t_preview_style .= ' max-width:' . $t_max_width . 'px;'; } $t_max_height = config_get( 'preview_max_height' ); if( $t_max_height > 0 ) { $t_preview_style .= ' max-height:' . $t_max_height . 'px;'; } $t_title = file_get_field( $p_attachment['id'], 'title' ); $t_image_url = $p_attachment['download_url'] . '&show_inline=1' . form_security_param( 'file_show_inline' ); echo "\n<div class=\"bug-attachment-preview-image\">"; echo '<a href="' . string_attribute( $p_attachment['download_url'] ) . '">'; echo '<img src="' . string_attribute( $t_image_url ) . '" alt="' . string_attribute( $t_title ) . '" style="' . string_attribute( $t_preview_style ) . '" />'; echo '</a></div>'; } /** * Print the option list for time zones * @param string $p_timezone Selected time zone. * @return void */ function print_timezone_option_list( $p_timezone ) { $t_identifiers = timezone_identifiers_list( DateTimeZone::ALL ); foreach( $t_identifiers as $t_identifier ) { $t_zone = explode( '/', $t_identifier, 2 ); if( isset( $t_zone[1] ) ) { $t_id = $t_zone[1]; } else { $t_id = $t_identifier; } $t_locations[$t_zone[0]][$t_identifier] = array( str_replace( '_', ' ', $t_id ), $t_identifier ); } foreach( $t_locations as $t_continent => $t_locations ) { echo "\t" . '<optgroup label="' . $t_continent . '">' . "\n"; foreach ( $t_locations as $t_location ) { echo "\t\t" . '<option value="' . $t_location[1] . '"'; check_selected( $p_timezone, $t_location[1] ); echo '>' . $t_location[0] . '</option>' . "\n"; } echo "\t" . '</optgroup>' . "\n"; } } /** * Return file size information * @param integer $p_size File size. * @param string $p_unit File size unit. * @return string */ function get_filesize_info( $p_size, $p_unit ) { return sprintf( lang_get( 'file_size_info' ), number_format( $p_size ), $p_unit ); } /** * Print maximum file size information * @param integer $p_size Size in bytes. * @param integer $p_divider Optional divider, defaults to 1000. * @param string $p_unit Optional language string of unit, defaults to KB. * @return void */ function print_max_filesize( $p_size, $p_divider = 1000, $p_unit = 'kb' ) { echo '<span class="small" title="' . get_filesize_info( $p_size, lang_get( 'bytes' ) ) . '">'; echo lang_get( 'max_file_size_label' ) . lang_get( 'word_separator' ) . get_filesize_info( $p_size / $p_divider, lang_get( $p_unit ) ); echo '</span>'; } print_api_original.php (71,375 bytes)
<?php # MantisBT - A PHP based bugtracking system # MantisBT is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # MantisBT is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with MantisBT. If not, see <http://www.gnu.org/licenses/>. /** * Print API * * @package CoreAPI * @subpackage PrintAPI * @copyright Copyright 2000 - 2002 Kenzaburo Ito - kenito@300baud.org * @copyright Copyright 2002 MantisBT Team - mantisbt-dev@lists.sourceforge.net * @link http://www.mantisbt.org * * @uses access_api.php * @uses authentication_api.php * @uses bug_group_action_api.php * @uses category_api.php * @uses config_api.php * @uses collapse_api.php * @uses constant_inc.php * @uses current_user_api.php * @uses custom_field_api.php * @uses database_api.php * @uses email_api.php * @uses error_api.php * @uses file_api.php * @uses form_api.php * @uses helper_api.php * @uses html_api.php * @uses lang_api.php * @uses last_visited_api.php * @uses news_api.php * @uses prepare_api.php * @uses profile_api.php * @uses project_api.php * @uses project_hierarchy_api.php * @uses string_api.php * @uses tag_api.php * @uses user_api.php * @uses utility_api.php * @uses version_api.php */ require_api( 'access_api.php' ); require_api( 'authentication_api.php' ); require_api( 'bug_group_action_api.php' ); require_api( 'category_api.php' ); require_api( 'config_api.php' ); require_api( 'collapse_api.php' ); require_api( 'constant_inc.php' ); require_api( 'current_user_api.php' ); require_api( 'custom_field_api.php' ); require_api( 'database_api.php' ); require_api( 'email_api.php' ); require_api( 'error_api.php' ); require_api( 'file_api.php' ); require_api( 'form_api.php' ); require_api( 'helper_api.php' ); require_api( 'html_api.php' ); require_api( 'lang_api.php' ); require_api( 'last_visited_api.php' ); require_api( 'news_api.php' ); require_api( 'prepare_api.php' ); require_api( 'profile_api.php' ); require_api( 'project_api.php' ); require_api( 'project_hierarchy_api.php' ); require_api( 'string_api.php' ); require_api( 'tag_api.php' ); require_api( 'user_api.php' ); require_api( 'utility_api.php' ); require_api( 'version_api.php' ); /** * Print the headers to cause the page to redirect to $p_url * If $p_die is true (default), terminate the execution of the script immediately * If we have handled any errors on this page return false and don't redirect. * $p_sanitize - true/false - true in the case where the URL is extracted from GET/POST or untrusted source. * This would be false if the URL is trusted (e.g. read from config_inc.php). * * @param string $p_url The page to redirect: has to be a relative path. * @param boolean $p_die If true, stop the script after redirecting. * @param boolean $p_sanitize Apply string_sanitize_url to passed URL. * @param boolean $p_absolute Indicate if URL is absolute. * @return boolean */ function print_header_redirect( $p_url, $p_die = true, $p_sanitize = false, $p_absolute = false ) { if( ON == config_get_global( 'stop_on_errors' ) && error_handled() ) { return false; } # validate the url as part of this site before continuing if( $p_absolute ) { if( $p_sanitize ) { $t_url = string_sanitize_url( $p_url ); } else { $t_url = $p_url; } } else { if( $p_sanitize ) { $t_url = string_sanitize_url( $p_url, true ); } else { $t_url = config_get( 'path' ) . $p_url; } } $t_url = string_prepare_header( $t_url ); # don't send more headers if they have already been sent if( !headers_sent() ) { header( 'Content-Type: text/html; charset=utf-8' ); header( 'Location: ' . $t_url ); } else { trigger_error( ERROR_PAGE_REDIRECTION, ERROR ); return false; } if( $p_die ) { die; # additional output can cause problems so let's just stop output here } return true; } /** * Print a redirect header to view a bug * * @param integer $p_bug_id A bug identifier. * @return void */ function print_header_redirect_view( $p_bug_id ) { print_header_redirect( string_get_bug_view_url( $p_bug_id ) ); } /** * Get a view URL for the bug id based on the user's preference and * call print_successful_redirect() with that URL * * @param integer $p_bug_id A bug identifier. * @return void */ function print_successful_redirect_to_bug( $p_bug_id ) { $t_url = string_get_bug_view_url( $p_bug_id ); print_successful_redirect( $t_url ); } /** * If the show query count is ON, print success and redirect after the configured system wait time. * If the show query count is OFF, redirect right away. * * @param string $p_redirect_to URI to redirect to. * @return void */ function print_successful_redirect( $p_redirect_to ) { if( helper_log_to_page() ) { html_page_top( null, $p_redirect_to ); echo '<br /><div class="center">'; echo lang_get( 'operation_successful' ) . '<br />'; print_bracket_link( $p_redirect_to, lang_get( 'proceed' ) ); echo '</div>'; html_page_bottom(); } else { print_header_redirect( $p_redirect_to ); } } /** * Print avatar image for the given user ID * * @param integer $p_user_id A user identifier. * @param integer $p_size Image pixel size. * @return void */ function print_avatar( $p_user_id, $p_size = 80 ) { $t_avatar = Avatar::get( $p_user_id, $p_size ); if( $t_avatar === null ) { return; } $t_image = htmlspecialchars( $t_avatar->image ); $t_link = htmlspecialchars( $t_avatar->link ); $t_text = htmlspecialchars( $t_avatar->text ); echo '<a rel="nofollow" href="' . $t_link . '">' . '<img class="avatar" src="' . $t_image . '" alt="' . $t_text . '" width="' . $p_size . '" height="' . $p_size . '" /></a>'; } /** * prints the name of the user given the id. also makes it an email link. * * @param integer $p_user_id A user identifier. * @return void */ function print_user( $p_user_id ) { echo prepare_user_name( $p_user_id ); } /** * same as echo get_user_name() but fills in the subject with the bug summary * * @param integer $p_user_id A user identifier. * @param integer $p_bug_id A bug identifier. * @return void */ function print_user_with_subject( $p_user_id, $p_bug_id ) { if( NO_USER == $p_user_id ) { return; } $t_username = user_get_name( $p_user_id ); if( user_exists( $p_user_id ) && user_get_field( $p_user_id, 'enabled' ) ) { $t_email = user_get_email( $p_user_id ); print_email_link_with_subject( $t_email, $t_username, $p_bug_id ); } else { echo '<span class="user" style="text-decoration: line-through">'; echo $t_username; echo '</span>'; } } /** * print out an email editing input * * @param string $p_field_name Name of input tag. * @param string $p_email Email address. * @return void */ function print_email_input( $p_field_name, $p_email ) { echo '<input id="email-field" type="text" name="' . string_attribute( $p_field_name ) . '" size="32" maxlength="64" value="' . string_attribute( $p_email ) . '" />'; } /** * print out an email editing input * * @param string $p_field_name Name of input tag. * @return void */ function print_captcha_input( $p_field_name ) { echo '<input id="captcha-field" type="text" name="' . $p_field_name . '" size="6" maxlength="6" value="" />'; } /** * This populates an option list with the appropriate users by access level * @todo from print_reporter_option_list * @param integer|array $p_user_id A user identifier or a list of them. * @param integer $p_project_id A project identifier. * @param integer $p_access An access level. * @return void */ function print_user_option_list( $p_user_id, $p_project_id = null, $p_access = ANYBODY ) { $t_current_user = auth_get_current_user_id(); if( null === $p_project_id ) { $p_project_id = helper_get_current_project(); } if( $p_project_id === ALL_PROJECTS ) { $t_projects = user_get_accessible_projects( $t_current_user ); # Get list of users having access level for all accessible projects $t_users = array(); foreach( $t_projects as $t_project_id ) { $t_project_users_list = project_get_all_user_rows( $t_project_id, $p_access ); # Do a 'smart' merge of the project's user list, into an # associative array (to remove duplicates) foreach( $t_project_users_list as $t_id => $t_user ) { $t_users[$t_id] = $t_user; } # Clear the array to release memory unset( $t_project_users_list ); } unset( $t_projects ); } else { $t_users = project_get_all_user_rows( $p_project_id, $p_access ); } # Add the specified user ID to the list # If we have an array of user IDs, then we've been called from a filter # so don't add anything if( !is_array( $p_user_id ) && $p_user_id != NO_USER && !array_key_exists( $p_user_id, $t_users ) ) { $t_row = user_cache_row( $p_user_id, /* trigger_error */ false ); if( $t_row === false ) { # User doesn't exist - create a dummy record for display purposes $t_name = user_get_name( $p_user_id ); $t_row = array( 'id' => $p_user_id, 'username' => $t_name, 'realname' => $t_name, ); } $t_users[$p_user_id] = $t_row; } $t_display = array(); $t_sort = array(); $t_show_realname = ( ON == config_get( 'show_realname' ) ); $t_sort_by_last_name = ( ON == config_get( 'sort_by_last_name' ) ); foreach( $t_users as $t_key => $t_user ) { $t_user_name = string_attribute( $t_user['username'] ); $t_sort_name = utf8_strtolower( $t_user_name ); if( $t_show_realname && ( $t_user['realname'] <> '' ) ) { $t_user_name = string_attribute( $t_user['realname'] ); if( $t_sort_by_last_name ) { $t_sort_name_bits = explode( ' ', utf8_strtolower( $t_user_name ), 2 ); $t_sort_name = ( isset( $t_sort_name_bits[1] ) ? $t_sort_name_bits[1] . ', ' : '' ) . $t_sort_name_bits[0]; } else { $t_sort_name = utf8_strtolower( $t_user_name ); } } $t_display[] = $t_user_name; $t_sort[] = $t_sort_name; } array_multisort( $t_sort, SORT_ASC, SORT_STRING, $t_users, $t_display ); unset( $t_sort ); $t_count = count( $t_users ); for( $i = 0;$i < $t_count;$i++ ) { $t_row = $t_users[$i]; echo '<option value="' . $t_row['id'] . '" '; check_selected( $p_user_id, (int)$t_row['id'] ); echo '>' . $t_display[$i] . '</option>'; } } /** * This populates the reporter option list with the appropriate users * * @todo ugly functions need to be refactored * @todo This function really ought to print out all the users, I think. * I just encountered a situation where a project used to be public and * was made private, so now I can't filter on any of the reporters who * actually reported the bugs at the time. Maybe we could get all user * who are listed as the reporter in any bug? It would probably be a * faster query actually. * @param integer $p_user_id A user identifier. * @param integer $p_project_id A project identifier. * @return void */ function print_reporter_option_list( $p_user_id, $p_project_id = null ) { print_user_option_list( $p_user_id, $p_project_id, config_get( 'report_bug_threshold' ) ); } /** * Print the entire form for attaching a tag to a bug. * @param integer $p_bug_id A bug identifier. * @param string $p_string Default contents of the input box. * @return boolean */ function print_tag_attach_form( $p_bug_id, $p_string = '' ) { ?> <small><?php echo sprintf( lang_get( 'tag_separate_by' ), config_get( 'tag_separator' ) )?></small> <form method="post" action="tag_attach.php"> <?php echo form_security_field( 'tag_attach' )?> <input type="hidden" name="bug_id" value="<?php echo $p_bug_id?>" /> <?php print_tag_input( $p_bug_id, $p_string ); ?> <input type="submit" value="<?php echo lang_get( 'tag_attach' )?>" class="button" /> </form> <?php return true; } /** * Print the separator comment, input box, and existing tag dropdown menu. * @param integer $p_bug_id A bug identifier. * @param string $p_string Default contents of the input box. * @return void */ function print_tag_input( $p_bug_id = 0, $p_string = '' ) { ?> <input type="hidden" id="tag_separator" value="<?php echo config_get( 'tag_separator' )?>" /> <input type="text" name="tag_string" id="tag_string" size="40" value="<?php echo string_attribute( $p_string )?>" /> <select <?php echo helper_get_tab_index()?> name="tag_select" id="tag_select"> <?php print_tag_option_list( $p_bug_id );?> </select> <?php } /** * Print out a list of errors for tags that failed validation or access check. * * @param array $p_tags_failed The array of failed tags. * @return void */ function print_tagging_errors_table( $p_tags_failed ) { ?> <div id="manage-user-div" class="form-container"> <h2><?php echo lang_get( 'tag_attach_failed' ) ?></h2> <table><tbody> <?php foreach( $p_tags_failed as $t_tag_row ) { echo '<tr>'; echo '<td>', string_html_specialchars( $t_tag_row['name'] ), '</td>'; if( -1 == $t_tag_row['id'] ) { $t_error = lang_get( 'tag_create_denied' ); } else if( -2 == $t_tag_row['id'] ) { $t_error = lang_get( 'tag_invalid_name' ); } echo '<td>', $t_error, '</td>'; echo '</tr>'; } ?> </tbody></table> </div> <?php } /** * Print the drop-down combo-box of existing tags. * When passed a bug ID, the option list will not contain any tags attached to the given bug. * @param integer $p_bug_id A bug identifier. * @return void */ function print_tag_option_list( $p_bug_id = 0 ) { $t_rows = tag_get_candidates_for_bug( $p_bug_id ); echo '<option value="0">', string_html_specialchars( lang_get( 'tag_existing' ) ), '</option>'; foreach ( $t_rows as $t_row ) { echo '<option value="', $t_row['id'], '" title="', string_attribute( $t_row['description'] ); echo '">', string_attribute( $t_row['name'] ), '</option>'; } } /** * Get current headlines and id prefix with v_ * @return void */ function print_news_item_option_list() { $t_project_id = helper_get_current_project(); $t_global = access_has_global_level( config_get_global( 'admin_site_threshold' ) ); db_param_push(); if( $t_global ) { $t_query = 'SELECT id, headline, announcement, view_state FROM {news} ORDER BY date_posted DESC'; } else { $t_query = 'SELECT id, headline, announcement, view_state FROM {news} WHERE project_id=' . db_param() . ' ORDER BY date_posted DESC'; } $t_result = db_query( $t_query, ($t_global == true ? array() : array( $t_project_id ) ) ); while( $t_row = db_fetch_array( $t_result ) ) { $t_headline = string_display( $t_row['headline'] ); $t_announcement = $t_row['announcement']; $t_view_state = $t_row['view_state']; $t_id = $t_row['id']; $t_notes = array(); $t_note_string = ''; if( 1 == $t_announcement ) { array_push( $t_notes, lang_get( 'announcement' ) ); } if( VS_PRIVATE == $t_view_state ) { array_push( $t_notes, lang_get( 'private' ) ); } if( count( $t_notes ) > 0 ) { $t_note_string = ' [' . implode( ' ', $t_notes ) . ']'; } echo '<option value="' . $t_id . '">' . $t_headline . $t_note_string . '</option>'; } } /** * Constructs the string for one news entry given the row retrieved from the news table. * * @param string $p_headline Headline of news article. * @param string $p_body Body text of news article. * @param integer $p_poster_id User ID of author. * @param integer $p_view_state View State - either VS_PRIVATE or VS_PUBLIC. * @param boolean $p_announcement Flagged if news should be an announcement. * @param integer $p_date_posted Date associated with news entry. * @return void */ function print_news_entry( $p_headline, $p_body, $p_poster_id, $p_view_state, $p_announcement, $p_date_posted ) { $t_headline = string_display_links( $p_headline ); $t_body = string_display_links( $p_body ); $t_date_posted = date( config_get( 'normal_date_format' ), $p_date_posted ); if( VS_PRIVATE == $p_view_state ) { $t_news_css = 'news-heading-private'; } else { $t_news_css = 'news-heading-public'; } ?> <div class="news-item"> <h3 class="<?php echo $t_news_css; ?>"> <span class="news-title"><?php echo $t_headline; ?></span> <span class="news-date-posted"><?php echo $t_date_posted; ?></span> <span class="news-author"><?php echo prepare_user_name( $p_poster_id ); ?></span><?php if( 1 == $p_announcement ) { ?> <span class="news-announcement"><?php echo lang_get( 'announcement' ); ?></span><?php } if( VS_PRIVATE == $p_view_state ) { ?> <span class="news-private"><?php echo lang_get( 'private' ); ?></span><?php } ?> </h3> <p class="news-body"><?php echo $t_body; ?></p> </div><?php } /** * print a news item given a row in the news table. * @param array $p_news_row A news database result. * @return void */ function print_news_entry_from_row( array $p_news_row ) { $t_headline = $p_news_row['headline']; $t_body = $p_news_row['body']; $t_poster_id = $p_news_row['poster_id']; $t_view_state = $p_news_row['view_state']; $t_announcement = $p_news_row['announcement']; $t_date_posted = $p_news_row['date_posted']; print_news_entry( $t_headline, $t_body, $t_poster_id, $t_view_state, $t_announcement, $t_date_posted ); } /** * print a news item * * @param integer $p_news_id A news article identifier. * @return void */ function print_news_string_by_news_id( $p_news_id ) { $t_row = news_get_row( $p_news_id ); # only show VS_PRIVATE posts to configured threshold and above if( ( VS_PRIVATE == $t_row['view_state'] ) && !access_has_project_level( config_get( 'private_news_threshold' ) ) ) { return; } print_news_entry_from_row( $t_row ); } /** * Print User option list for assigned to field * @param integer|string $p_user_id A user identifier. * @param integer $p_project_id A project identifier. * @param integer $p_threshold An access level. * @return void */ function print_assign_to_option_list( $p_user_id = '', $p_project_id = null, $p_threshold = null ) { if( null === $p_threshold ) { $p_threshold = config_get( 'handle_bug_threshold' ); } print_user_option_list( $p_user_id, $p_project_id, $p_threshold ); } /** * Print User option list for bugnote filter field * @param integer|string $p_user_id A user identifier. * @param integer $p_project_id A project identifier. * @param integer $p_threshold An access level. * @return void */ function print_note_option_list( $p_user_id = '', $p_project_id = null, $p_threshold = null ) { if( null === $p_threshold ) { $p_threshold = config_get( 'add_bugnote_threshold' ); } print_user_option_list( $p_user_id, $p_project_id, $p_threshold ); } /** * List projects that the current user has access to. * * @param integer $p_project_id The current project id or null to use cookie. * @param boolean $p_include_all_projects True: include "All Projects", otherwise false. * @param integer|null $p_filter_project_id The id of a project to exclude or null. * @param string|boolean $p_trace The current project trace, identifies the sub-project via a path from top to bottom. * @param boolean $p_can_report_only If true, disables projects in which user can't report issues; defaults to false (all projects enabled). * @return void */ function print_project_option_list( $p_project_id = null, $p_include_all_projects = true, $p_filter_project_id = null, $p_trace = false, $p_can_report_only = false ) { $t_user_id = auth_get_current_user_id(); $t_project_ids = user_get_accessible_projects( $t_user_id ); $t_can_report = true; project_cache_array_rows( $t_project_ids ); if( $p_include_all_projects && $p_filter_project_id !== ALL_PROJECTS ) { echo '<option value="' . ALL_PROJECTS . '"'; if( $p_project_id !== null ) { check_selected( $p_project_id, ALL_PROJECTS, false ); } echo '>' . lang_get( 'all_projects' ) . '</option>' . "\n"; } foreach( $t_project_ids as $t_id ) { if( $p_can_report_only ) { $t_report_bug_threshold = config_get( 'report_bug_threshold', null, $t_user_id, $t_id ); $t_can_report = access_has_project_level( $t_report_bug_threshold, $t_id, $t_user_id ); } echo '<option value="' . $t_id . '"'; check_selected( $p_project_id, $t_id, false ); check_disabled( $t_id == $p_filter_project_id || !$t_can_report ); echo '>' . string_attribute( project_get_field( $t_id, 'name' ) ) . '</option>' . "\n"; print_subproject_option_list( $t_id, $p_project_id, $p_filter_project_id, $p_trace, $p_can_report_only ); } } /** * List projects that the current user has access to * @param integer $p_parent_id A parent project identifier. * @param integer $p_project_id A project identifier. * @param integer $p_filter_project_id A filter project identifier. * @param boolean $p_trace Whether to trace parent projects. * @param boolean $p_can_report_only If true, disables projects in which user can't report issues; defaults to false (all projects enabled). * @param array $p_parents Array of parent projects. * @return void */ function print_subproject_option_list( $p_parent_id, $p_project_id = null, $p_filter_project_id = null, $p_trace = false, $p_can_report_only = false, array $p_parents = array() ) { if ( config_get( 'subprojects_enabled' ) == OFF ) { return; } array_push( $p_parents, $p_parent_id ); $t_user_id = auth_get_current_user_id(); $t_project_ids = user_get_accessible_subprojects( $t_user_id, $p_parent_id ); project_cache_array_rows( $t_project_ids ); $t_can_report = true; foreach( $t_project_ids as $t_id ) { if( $p_can_report_only ) { $t_report_bug_threshold = config_get( 'report_bug_threshold', null, $t_user_id, $t_id ); $t_can_report = access_has_project_level( $t_report_bug_threshold, $t_id, $t_user_id ); } if( $p_trace ) { $t_full_id = join( $p_parents, ';' ) . ';' . $t_id; } else { $t_full_id = $t_id; } echo '<option value="' . $t_full_id . '"'; check_selected( $p_project_id, $t_full_id, false ); check_disabled( $t_id == $p_filter_project_id || !$t_can_report ); echo '>' . str_repeat( ' ', count( $p_parents ) ) . str_repeat( '»', count( $p_parents ) ) . ' ' . string_attribute( project_get_field( $t_id, 'name' ) ) . '</option>' . "\n"; print_subproject_option_list( $t_id, $p_project_id, $p_filter_project_id, $p_trace, $p_can_report_only, $p_parents ); } } /** * prints the profiles given the user id * @param integer $p_user_id A user identifier. * @param integer $p_select_id ID to mark as selected; if 0, gets the user's default profile. * @param array $p_profiles Array of profiles. * @return void */ function print_profile_option_list( $p_user_id, $p_select_id = 0, array $p_profiles = null ) { if( 0 == $p_select_id ) { $p_select_id = profile_get_default( $p_user_id ); } if( $p_profiles != null ) { $t_profiles = $p_profiles; } else { $t_profiles = profile_get_all_for_user( $p_user_id ); } print_profile_option_list_from_profiles( $t_profiles, $p_select_id ); } /** * prints the profiles used in a certain project * @param integer $p_project_id A project identifier. * @param integer $p_select_id ID to mark as selected; if 0, gets the user's default profile. * @param array $p_profiles Array of profiles. * @return void */ function print_profile_option_list_for_project( $p_project_id, $p_select_id = 0, array $p_profiles = null ) { if( 0 == $p_select_id ) { $p_select_id = profile_get_default( auth_get_current_user_id() ); } if( $p_profiles != null ) { $t_profiles = $p_profiles; } else { $t_profiles = profile_get_all_for_project( $p_project_id ); } print_profile_option_list_from_profiles( $t_profiles, $p_select_id ); } /** * print the profile option list from profiles array * * @param array $p_profiles Array of Operating System Profiles (ID, platform, os, os_build). * @param integer $p_select_id ID to mark as selected. * @return void */ function print_profile_option_list_from_profiles( array $p_profiles, $p_select_id ) { echo '<option value="">' . lang_get( 'select_option' ) . '</option>'; foreach( $p_profiles as $t_profile ) { extract( $t_profile, EXTR_PREFIX_ALL, 'v' ); $t_platform = string_attribute( $t_profile['platform'] ); $t_os = string_attribute( $t_profile['os'] ); $t_os_build = string_attribute( $t_profile['os_build'] ); echo '<option value="' . $t_profile['id'] . '"'; if( $p_select_id !== false ) { check_selected( $p_select_id, (int)$t_profile['id'] ); } echo '>' . $t_platform . ' ' . $t_os . ' ' . $t_os_build . '</option>'; } } /** * Since categories can be orphaned we need to grab all unique instances of category * We check in the project category table and in the bug table * We put them all in one array and make sure the entries are unique * * @param integer $p_category_id A category identifier. * @param integer $p_project_id A project identifier. * @return void */ function print_category_option_list( $p_category_id = 0, $p_project_id = null ) { if( null === $p_project_id ) { $t_project_id = helper_get_current_project(); } else { $t_project_id = $p_project_id; } $t_cat_arr = category_get_all_rows( $t_project_id, null, true ); if( config_get( 'allow_no_category' ) ) { echo '<option value="0"'; check_selected( $p_category_id, 0 ); echo '>'; echo category_full_name( 0, false ), '</option>'; } else { if( 0 == $p_category_id ) { if( count( $t_cat_arr ) == 1 ) { $p_category_id = (int) $t_cat_arr[0]['id']; } else { echo '<option value="0"'; echo check_selected( $p_category_id, 0 ); echo '>'; echo string_attribute( lang_get( 'select_option' ) ) . '</option>'; } } } foreach( $t_cat_arr as $t_category_row ) { $t_category_id = (int)$t_category_row['id']; echo '<option value="' . $t_category_id . '"'; check_selected( $p_category_id, $t_category_id ); echo '>' . string_attribute( category_full_name( $t_category_id, $t_category_row['project_id'] != $t_project_id ) ) . '</option>'; } } /** * Now that categories are identified by numerical ID, we need an old-style name * based option list to keep existing filter functionality. * @param string $p_category_name The selected category. * @param integer|null $p_project_id A specific project or null. * @return void */ function print_category_filter_option_list( $p_category_name = '', $p_project_id = null ) { $t_cat_arr = category_get_filter_list( $p_project_id ); natcasesort( $t_cat_arr ); foreach( $t_cat_arr as $t_cat ) { $t_name = string_attribute( $t_cat ); echo '<option value="' . $t_name . '"'; check_selected( $p_category_name, $t_cat ); echo '>' . $t_name . '</option>'; } } /** * Print the option list for platforms accessible for the specified user. * @param string $p_platform The current platform value. * @param integer $p_user_id A user identifier. * @return void */ function print_platform_option_list( $p_platform, $p_user_id = null ) { $t_platforms_array = profile_get_field_all_for_user( 'platform', $p_user_id ); foreach( $t_platforms_array as $t_platform_unescaped ) { $t_platform = string_attribute( $t_platform_unescaped ); echo '<option value="' . $t_platform . '"'; check_selected( $p_platform, $t_platform_unescaped ); echo '>' . $t_platform . '</option>'; } } /** * Print the option list for OSes accessible for the specified user. * @param string $p_os The current operating system value. * @param integer $p_user_id A user identifier. * @return void */ function print_os_option_list( $p_os, $p_user_id = null ) { $t_os_array = profile_get_field_all_for_user( 'os', $p_user_id ); foreach( $t_os_array as $t_os_unescaped ) { $t_os = string_attribute( $t_os_unescaped ); echo '<option value="' . $t_os . '"'; check_selected( $p_os, $t_os_unescaped ); echo '>' . $t_os . '</option>'; } } /** * Print the option list for os_build accessible for the specified user. * @param string $p_os_build The current operating system build value. * @param integer $p_user_id A user identifier. * @return void */ function print_os_build_option_list( $p_os_build, $p_user_id = null ) { $t_os_build_array = profile_get_field_all_for_user( 'os_build', $p_user_id ); foreach( $t_os_build_array as $t_os_build_unescaped ) { $t_os_build = string_attribute( $t_os_build_unescaped ); echo '<option value="' . $t_os_build . '"'; check_selected( $p_os_build, $t_os_build_unescaped ); echo '>' . $t_os_build . '</option>'; } } /** * Print the option list for versions * @param string $p_version The currently selected version. * @param integer $p_project_id Project id, otherwise current project will be used. * @param integer $p_released Null to get all, 1: only released, 0: only future versions. * @param boolean $p_leading_blank Allow selection of no version. * @param boolean $p_with_subs Whether to include sub-projects. * @return void */ function print_version_option_list( $p_version = '', $p_project_id = null, $p_released = null, $p_leading_blank = true, $p_with_subs = false ) { if( null === $p_project_id ) { $c_project_id = helper_get_current_project(); } else { $c_project_id = (int)$p_project_id; } if( $p_with_subs ) { $t_versions = version_get_all_rows_with_subs( $c_project_id, $p_released, null ); } else { $t_versions = version_get_all_rows( $c_project_id, $p_released, null ); } # Ensure the selected version (if specified) is included in the list # Note: Filter API specifies selected versions as an array if( !is_array( $p_version ) ) { if( !empty( $p_version ) ) { $t_version_id = version_get_id( $p_version, $c_project_id ); if( $t_version_id !== false ) { $t_versions[] = version_cache_row( $t_version_id ); } } } if( $p_leading_blank ) { echo '<option value=""></option>'; } $t_listed = array(); $t_max_length = config_get( 'max_dropdown_length' ); foreach( $t_versions as $t_version ) { # If the current version is obsolete, and current version not equal to $p_version, # then skip it. if( ( (int)$t_version['obsolete'] ) == 1 ) { if( $t_version['version'] != $p_version ) { continue; } } $t_version_version = string_attribute( $t_version['version'] ); if( !in_array( $t_version_version, $t_listed, true ) ) { $t_listed[] = $t_version_version; echo '<option value="' . $t_version_version . '"'; check_selected( $p_version, $t_version['version'] ); $t_version_string = string_attribute( prepare_version_string( $c_project_id, $t_version['id'] ) ); echo '>', string_shorten( $t_version_string, $t_max_length ), '</option>'; } } } /** * print build option list * @param string $p_build The current build value. * @return void */ function print_build_option_list( $p_build = '' ) { $t_overall_build_arr = array(); $t_project_id = helper_get_current_project(); $t_project_where = helper_project_specific_where( $t_project_id ); # Get the "found in" build list $t_query = 'SELECT DISTINCT build FROM {bug} WHERE ' . $t_project_where . ' ORDER BY build DESC'; $t_result = db_query( $t_query ); while( $t_row = db_fetch_array( $t_result ) ) { $t_overall_build_arr[] = $t_row['build']; } $t_max_length = config_get( 'max_dropdown_length' ); foreach( $t_overall_build_arr as $t_build_unescaped ) { $t_build = string_attribute( $t_build_unescaped ); echo '<option value="' . $t_build . '"'; check_selected( $p_build, $t_build_unescaped ); echo '>' . string_shorten( $t_build, $t_max_length ) . '</option>'; } } /** * select the proper enumeration values based on the input parameter * Current value may be an integer, or an array of integers. * @param string $p_enum_name Name of enumeration (eg: status). * @param integer|array $p_val The current value(s) * @return void */ function print_enum_string_option_list( $p_enum_name, $p_val = 0 ) { $t_config_var_name = $p_enum_name . '_enum_string'; $t_config_var_value = config_get( $t_config_var_name ); if( is_array( $p_val ) ) { $t_val = $p_val; } else { $t_val = (int)$p_val; } $t_enum_values = MantisEnum::getValues( $t_config_var_value ); foreach ( $t_enum_values as $t_key ) { $t_elem2 = get_enum_element( $p_enum_name, $t_key ); echo '<option value="' . $t_key . '"'; check_selected( $t_val, $t_key ); echo '>' . string_html_specialchars( $t_elem2 ) . '</option>'; } } /** * Select the proper enumeration values for status based on workflow * or the input parameter if workflows are not used * @param integer $p_user_auth A user identifier. * @param integer $p_current_value The current value. * @param boolean $p_show_current Whether to show the current status. * @param boolean $p_add_close Whether to add close option. * @param integer $p_project_id A project identifier. * @return array */ function get_status_option_list( $p_user_auth = 0, $p_current_value = 0, $p_show_current = true, $p_add_close = false, $p_project_id = ALL_PROJECTS ) { $t_config_var_value = config_get( 'status_enum_string', null, null, $p_project_id ); $t_enum_workflow = config_get( 'status_enum_workflow', null, null, $p_project_id ); if( count( $t_enum_workflow ) < 1 || !MantisEnum::hasValue( $t_config_var_value, $p_current_value ) ) { # workflow not defined, use default enumeration $t_enum_values = MantisEnum::getValues( $t_config_var_value ); } else { # workflow defined - find allowed states if( isset( $t_enum_workflow[$p_current_value] ) ) { $t_enum_values = MantisEnum::getValues( $t_enum_workflow[$p_current_value] ); } else { # workflow was not set for this status, this shouldn't happen # caller should be able to handle empty list $t_enum_values = array(); } } $t_enum_list = array(); foreach ( $t_enum_values as $t_enum_value ) { if( ( $p_show_current || $p_current_value != $t_enum_value ) && access_compare_level( $p_user_auth, access_get_status_threshold( $t_enum_value, $p_project_id ) ) ) { $t_enum_list[$t_enum_value] = get_enum_element( 'status', $t_enum_value ); } } if( $p_show_current ) { $t_enum_list[$p_current_value] = get_enum_element( 'status', $p_current_value ); } if( $p_add_close && access_compare_level( $p_current_value, config_get( 'bug_resolved_status_threshold', null, null, $p_project_id ) ) ) { $t_closed = config_get( 'bug_closed_status_threshold', null, null, $p_project_id ); if( $p_show_current || $p_current_value != $t_closed ) { $t_enum_list[$t_closed] = get_enum_element( 'status', $t_closed ); } } return $t_enum_list; } /** * print the status option list for the bug_update pages * @param string $p_select_label The id/name html attribute of the select box. * @param integer $p_current_value The current value. * @param boolean $p_allow_close Whether to allow close. * @param integer $p_project_id A project identifier. * @return void */ function print_status_option_list( $p_select_label, $p_current_value = 0, $p_allow_close = false, $p_project_id = ALL_PROJECTS ) { $t_current_auth = access_get_project_level( $p_project_id ); $t_enum_list = get_status_option_list( $t_current_auth, $p_current_value, true, $p_allow_close, $p_project_id ); if( count( $t_enum_list ) > 1 ) { # resort the list into ascending order ksort( $t_enum_list ); reset( $t_enum_list ); echo '<select ' . helper_get_tab_index() . ' id="' . $p_select_label . '" name="' . $p_select_label . '">'; foreach( $t_enum_list as $t_key => $t_val ) { echo '<option value="' . $t_key . '"'; check_selected( $t_key, $p_current_value ); echo '>' . string_html_specialchars( $t_val ) . '</option>'; } echo '</select>'; } else if( count( $t_enum_list ) == 1 ) { echo array_pop( $t_enum_list ); } else { echo MantisEnum::getLabel( lang_get( 'status_enum_string' ), $p_current_value ); } } /** * prints the list of a project's users * if no project is specified uses the current project * @param integer $p_project_id A project identifier. * @return void */ function print_project_user_option_list( $p_project_id = null ) { print_user_option_list( 0, $p_project_id ); } /** * prints the list of access levels that are less than or equal to the access level of the * logged in user. This is used when adding users to projects * @param integer $p_val The current value. * @param integer $p_project_id A project identifier. * @return void */ function print_project_access_levels_option_list( $p_val, $p_project_id = null ) { $t_current_user_access_level = access_get_project_level( $p_project_id ); $t_access_levels_enum_string = config_get( 'access_levels_enum_string' ); $t_enum_values = MantisEnum::getValues( $t_access_levels_enum_string ); foreach ( $t_enum_values as $t_enum_value ) { # a user must not be able to assign another user an access level that is higher than theirs. if( $t_enum_value > $t_current_user_access_level ) { continue; } $t_access_level = get_enum_element( 'access_levels', $t_enum_value ); echo '<option value="' . $t_enum_value . '"'; check_selected( $p_val, $t_enum_value ); echo '>' . string_html_specialchars( $t_access_level ) . '</option>'; } } /** * Print option list of available language choices * @param string $p_language The current language. * @return void */ function print_language_option_list( $p_language ) { $t_arr = config_get( 'language_choices_arr' ); $t_enum_count = count( $t_arr ); for( $i = 0;$i < $t_enum_count;$i++ ) { $t_language = string_attribute( $t_arr[$i] ); echo '<option value="' . $t_language . '"'; check_selected( $t_language, $p_language ); echo '>' . $t_language . '</option>'; } } /** * Print a dropdown list of all bug actions available to a user for a specified * set of projects. * @param array $p_project_ids An array containing one or more project IDs. * @return void */ function print_all_bug_action_option_list( array $p_project_ids = null ) { $t_commands = bug_group_action_get_commands( $p_project_ids ); while( list( $t_action_id, $t_action_label ) = each( $t_commands ) ) { echo '<option value="' . $t_action_id . '">' . $t_action_label . '</option>'; } } /** * list of users that are NOT in the specified project and that are enabled * if no project is specified use the current project * also exclude any administrators * @param integer $p_project_id A project identifier. * @return void */ function print_project_user_list_option_list( $p_project_id = null ) { $t_users = user_get_unassigned_by_project_id( $p_project_id ); foreach( $t_users as $t_id=>$t_name ) { echo '<option value="' . $t_id . '">' . $t_name . '</option>'; } } /** * list of projects that a user is NOT in * @param integer $p_user_id An user identifier. * @return void */ function print_project_user_list_option_list2( $p_user_id ) { db_param_push(); $t_query = 'SELECT DISTINCT p.id, p.name FROM {project} p LEFT JOIN {project_user_list} u ON p.id=u.project_id AND u.user_id=' . db_param() . ' WHERE p.enabled = ' . db_param() . ' AND u.user_id IS NULL ORDER BY p.name'; $t_result = db_query( $t_query, array( (int)$p_user_id, true ) ); $t_category_count = db_num_rows( $t_result ); while( $t_row = db_fetch_array( $t_result ) ) { $t_project_name = string_attribute( $t_row['name'] ); $t_user_id = $t_row['id']; echo '<option value="' . $t_user_id . '">' . $t_project_name . '</option>'; } } /** * list of projects that a user is in * @param integer $p_user_id An user identifier. * @param boolean $p_include_remove_link Whether to display remove link. * @return void */ function print_project_user_list( $p_user_id, $p_include_remove_link = true ) { $t_projects = user_get_assigned_projects( $p_user_id ); foreach( $t_projects as $t_project_id=>$t_project ) { $t_project_name = string_attribute( $t_project['name'] ); $t_view_state = $t_project['view_state']; $t_access_level = $t_project['access_level']; $t_access_level = get_enum_element( 'access_levels', $t_access_level ); $t_view_state = get_enum_element( 'project_view_state', $t_view_state ); echo $t_project_name . ' [' . $t_access_level . '] (' . $t_view_state . ')'; if( $p_include_remove_link && access_has_project_level( config_get( 'project_user_threshold' ), $t_project_id ) ) { html_button( 'manage_user_proj_delete.php', lang_get( 'remove_link' ), array( 'project_id' => $t_project_id, 'user_id' => $p_user_id ) ); } echo '<br />'; } } /** * List of projects with which the specified field id is linked. * For every project, the project name is listed and then the list of custom * fields linked in order with their sequence numbers. The specified field * is always highlighted in italics and project names in bold. * * @param integer $p_field_id The field to list the projects associated with. * @return void */ function print_custom_field_projects_list( $p_field_id ) { $c_field_id = (integer)$p_field_id; $t_project_ids = custom_field_get_project_ids( $p_field_id ); $t_security_token = form_security_param( 'manage_proj_custom_field_remove' ); foreach( $t_project_ids as $t_project_id ) { $t_project_name = project_get_field( $t_project_id, 'name' ); $t_sequence = custom_field_get_sequence( $p_field_id, $t_project_id ); echo '<strong>', string_display_line( $t_project_name ), '</strong>: '; print_bracket_link( 'manage_proj_custom_field_remove.php?field_id=' . $c_field_id . '&project_id=' . $t_project_id . '&return=custom_field' . $t_security_token, lang_get( 'remove_link' ) ); echo '<br />- '; $t_linked_field_ids = custom_field_get_linked_ids( $t_project_id ); $t_first = true; foreach( $t_linked_field_ids as $t_current_field_id ) { if( $t_first ) { $t_first = false; } else { echo ', '; } if( $t_current_field_id == $p_field_id ) { echo '<em>'; } echo string_display_line( custom_field_get_field( $t_current_field_id, 'name' ) ); echo ' (', custom_field_get_sequence( $t_current_field_id, $t_project_id ), ')'; if( $t_current_field_id == $p_field_id ) { echo '</em>'; } } echo '<br /><br />'; } } /** * List of priorities that can be assigned to a plugin. * @param integer $p_priority Current priority. * @return void */ function print_plugin_priority_list( $p_priority ) { if( $p_priority < 1 && $p_priority > 5 ) { echo '<option value="', $p_priority, '" selected="selected">', $p_priority, '</option>'; } for( $i = 5;$i >= 1;$i-- ) { echo '<option value="', $i, '" ', check_selected( $p_priority, $i ), ' >', $i, '</option>'; } } /** * prints a link to VIEW a bug given an ID * account for the user preference and site override * @param integer $p_bug_id A bug identifier. * @param boolean $p_detail_info Detail info to display with the link. * @return void */ function print_bug_link( $p_bug_id, $p_detail_info = true ) { echo string_get_bug_view_link( $p_bug_id, $p_detail_info ); } /** * formats the priority given the status * shows the priority in BOLD if the bug is NOT closed and is of significant priority * @param BugData $p_bug Bug Object. * @return void */ function print_formatted_priority_string( BugData $p_bug ) { $t_pri_str = get_enum_element( 'priority', $p_bug->priority, auth_get_current_user_id(), $p_bug->project_id ); $t_priority_threshold = config_get( 'priority_significant_threshold' ); if( $t_priority_threshold >= 0 && $p_bug->priority >= $t_priority_threshold && $p_bug->status < config_get( 'bug_closed_status_threshold' ) ) { echo '<span class="bold">' . $t_pri_str . '</span>'; } else { echo $t_pri_str; } } /** * formats the severity given the status * shows the severity in BOLD if the bug is NOT closed and is of significant severity * @param BugData $p_bug Bug Object. * @return void */ function print_formatted_severity_string( BugData $p_bug ) { $t_sev_str = get_enum_element( 'severity', $p_bug->severity, auth_get_current_user_id(), $p_bug->project_id ); $t_severity_threshold = config_get( 'severity_significant_threshold' ); if( $t_severity_threshold >= 0 && $p_bug->severity >= $t_severity_threshold && $p_bug->status < config_get( 'bug_closed_status_threshold' ) ) { echo '<span class="bold">' . $t_sev_str . '</span>'; } else { echo $t_sev_str; } } /** * Print view bug sort link * @todo params should be in same order as print_manage_user_sort_link * @param string $p_string The displayed text of the link. * @param string $p_sort_field The field to sort. * @param string $p_sort The field to sort by. * @param string $p_dir The sort direction - either ASC or DESC. * @param integer $p_columns_target See COLUMNS_TARGET_* in constant_inc.php. * @return void */ function print_view_bug_sort_link( $p_string, $p_sort_field, $p_sort, $p_dir, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) { if( $p_columns_target == COLUMNS_TARGET_PRINT_PAGE ) { if( $p_sort_field == $p_sort ) { # We toggle between ASC and DESC if the user clicks the same sort order if( 'ASC' == $p_dir ) { $p_dir = 'DESC'; } else { $p_dir = 'ASC'; } } else { # Otherwise always start with ascending $p_dir = 'ASC'; } $t_sort_field = rawurlencode( $p_sort_field ); print_link( 'view_all_set.php?sort=' . $t_sort_field . '&dir=' . $p_dir . '&type=2&print=1', $p_string ); } else if( $p_columns_target == COLUMNS_TARGET_VIEW_PAGE ) { if( $p_sort_field == $p_sort ) { # we toggle between ASC and DESC if the user clicks the same sort order if( 'ASC' == $p_dir ) { $p_dir = 'DESC'; } else { $p_dir = 'ASC'; } } else { # Otherwise always start with ascending $p_dir = 'ASC'; } $t_sort_field = rawurlencode( $p_sort_field ); print_link( 'view_all_set.php?sort=' . $t_sort_field . '&dir=' . $p_dir . '&type=2', $p_string ); } else { echo $p_string; } } /** * Print manage user sort link * @param string $p_page The page within mantis to link to. * @param string $p_string The displayed text of the link. * @param string $p_field The field to sort. * @param string $p_dir The sort direction - either ASC or DESC. * @param string $p_sort_by The field to sort by. * @param integer $p_hide_inactive Whether to hide inactive users. * @param integer $p_filter The filter to use. * @param integer $p_show_disabled Whether to show disabled users. * @return void */ function print_manage_user_sort_link( $p_page, $p_string, $p_field, $p_dir, $p_sort_by, $p_hide_inactive = 0, $p_filter = ALL, $p_show_disabled = 0 ) { if( $p_sort_by == $p_field ) { # If this is the selected field flip the order if( 'ASC' == $p_dir || ASCENDING == $p_dir ) { $t_dir = 'DESC'; } else { $t_dir = 'ASC'; } } else { # Otherwise always start with ASCending $t_dir = 'ASC'; } $t_field = rawurlencode( $p_field ); print_link( $p_page . '?sort=' . $t_field . '&dir=' . $t_dir . '&save=1&hideinactive=' . $p_hide_inactive . '&showdisabled=' . $p_show_disabled . '&filter=' . $p_filter, $p_string ); } /** * Print manage project sort link * @param string $p_page The page within mantis to link to. * @param string $p_string The displayed text of the link. * @param string $p_field The field to sort. * @param string $p_dir The sort direction - either ASC or DESC. * @param string $p_sort_by The field to sort by. * @return void */ function print_manage_project_sort_link( $p_page, $p_string, $p_field, $p_dir, $p_sort_by ) { if( $p_sort_by == $p_field ) { # If this is the selected field flip the order if( 'ASC' == $p_dir || ASCENDING == $p_dir ) { $t_dir = 'DESC'; } else { $t_dir = 'ASC'; } } else { # Otherwise always start with ASCending $t_dir = 'ASC'; } $t_field = rawurlencode( $p_field ); print_link( $p_page . '?sort=' . $t_field . '&dir=' . $t_dir, $p_string ); } /** * Print a button which presents a standalone form. * If $p_security_token is OFF, the button's form will not contain a security * field; this is useful when form does not result in modifications (CSRF is not * needed). If otherwise specified (i.e. not null), the parameter must contain * a valid security token, previously generated by form_security_token(). * Use this to avoid performance issues when loading pages having many calls to * this function, such as adm_config_report.php. * @param string $p_action_page The action page. * @param string $p_label The button label. * @param array $p_args_to_post Associative array of arguments to be posted, with * arg name => value, defaults to null (no args). * @param mixed $p_security_token Optional; null (default), OFF or security token string. * @see form_security_token() * @return void */ function print_button( $p_action_page, $p_label, array $p_args_to_post = null, $p_security_token = null ) { $t_form_name = explode( '.php', $p_action_page, 2 ); # TODO: ensure all uses of print_button supply arguments via $p_args_to_post (POST) # instead of via $p_action_page (GET). Then only add the CSRF form token if # arguments are being sent via the POST method. echo '<form method="post" action="', htmlspecialchars( $p_action_page ), '" class="action-button">'; echo '<fieldset>'; if( $p_security_token !== OFF ) { echo form_security_field( $t_form_name[0], $p_security_token ); } echo '<input type="submit" class="button-small" value="', $p_label, '" />'; if( $p_args_to_post !== null ) { foreach( $p_args_to_post as $t_var => $t_value ) { echo '<input type="hidden" name="' . $t_var . '" value="' . htmlentities( $t_value ) . '" />'; } } echo '</fieldset>'; echo '</form>'; } /** * print brackets around a pre-prepared link (i.e. '<a href' html tag). * @param string $p_link The URL to link to. * @return void */ function print_bracket_link_prepared( $p_link ) { echo '<span class="bracket-link">[ ' . $p_link . ' ]</span> '; } /** * print the bracketed links used near the top * if the $p_link is blank then the text is printed but no link is created * if $p_new_window is true, link will open in a new window, default false. * @param string $p_link The URL to link to. * @param string $p_url_text The text to display. * @param boolean $p_new_window Whether to open in a new window. * @param string $p_class CSS class to use with the link. * @return void */ function print_bracket_link( $p_link, $p_url_text, $p_new_window = false, $p_class = '' ) { echo '<span class="bracket-link'; if( $p_class !== '' ) { echo ' bracket-link-',$p_class; # prefix on a container allows styling of whole link, including brackets } echo '">[ '; print_link( $p_link, $p_url_text, $p_new_window, $p_class ); echo ' ]</span> '; } /** * print a HTML link * @param string $p_link The page URL. * @param string $p_url_text The displayed text for the link. * @param boolean $p_new_window Whether to open in a new window. * @param string $p_class The CSS class of the link. * @return void */ function print_link( $p_link, $p_url_text, $p_new_window = false, $p_class = '' ) { if( is_blank( $p_link ) ) { echo $p_url_text; } else { $t_link = htmlspecialchars( $p_link ); if( $p_new_window === true ) { echo '<a class="new-window ' . $p_class . '" href="' . $t_link . '" target="_blank">' . $p_url_text . '</a>'; } else { if( $p_class !== '' ) { echo '<a class="' . $p_class . '" href="' . $t_link . '">' . $p_url_text . '</a>'; } else { echo '<a href="' . $t_link . '">' . $p_url_text . '</a>'; } } } } /** * print a HTML page link * @param string $p_page_url The Page URL. * @param string $p_text The displayed text for the link. * @param integer $p_page_no The page number to link to. * @param integer $p_page_cur The current page number. * @param integer $p_temp_filter_id Temporary filter id. * @return void */ function print_page_link( $p_page_url, $p_text = '', $p_page_no = 0, $p_page_cur = 0, $p_temp_filter_id = 0 ) { if( is_blank( $p_text ) ) { $p_text = $p_page_no; } if( ( 0 < $p_page_no ) && ( $p_page_no != $p_page_cur ) ) { $t_delimiter = ( strpos( $p_page_url, '?' ) ? '&' : '?' ); if( $p_temp_filter_id !== 0 ) { print_link( $p_page_url . $t_delimiter . 'filter=' . $p_temp_filter_id . '&page_number=' . $p_page_no, $p_text ); } else { print_link( $p_page_url . $t_delimiter . 'page_number=' . $p_page_no, $p_text ); } } else { echo $p_text; } } /** * print a list of page number links (eg [1 2 3]) * @param string $p_page The Page URL. * @param integer $p_start The first page number. * @param integer $p_end The last page number. * @param integer $p_current The current page number. * @param integer $p_temp_filter_id Temporary filter id. * @return void */ function print_page_links( $p_page, $p_start, $p_end, $p_current, $p_temp_filter_id = 0 ) { $t_items = array(); # Check if we have more than one page, # otherwise return without doing anything. if( $p_end - $p_start < 1 ) { return; } # Get localized strings $t_first = lang_get( 'first' ); $t_last = lang_get( 'last' ); $t_prev = lang_get( 'prev' ); $t_next = lang_get( 'next' ); $t_page_links = 10; print( '[ ' ); # First and previous links print_page_link( $p_page, $t_first, 1, $p_current, $p_temp_filter_id ); echo ' '; print_page_link( $p_page, $t_prev, $p_current - 1, $p_current, $p_temp_filter_id ); echo ' '; # Page numbers ... $t_first_page = max( $p_start, $p_current - $t_page_links / 2 ); $t_first_page = min( $t_first_page, $p_end - $t_page_links ); $t_first_page = max( $t_first_page, $p_start ); if( $t_first_page > 1 ) { print( ' ... ' ); } $t_last_page = $t_first_page + $t_page_links; $t_last_page = min( $t_last_page, $p_end ); for( $i = $t_first_page;$i <= $t_last_page;$i++ ) { if( $i == $p_current ) { array_push( $t_items, $i ); } else { $t_delimiter = ( strpos( $p_page, '?' ) ? '&' : '?' ) ; if( $p_temp_filter_id !== 0 ) { array_push( $t_items, '<a href="' . $p_page . $t_delimiter . 'filter=' . $p_temp_filter_id . '&page_number=' . $i . '">' . $i . '</a>' ); } else { array_push( $t_items, '<a href="' . $p_page . $t_delimiter . 'page_number=' . $i . '">' . $i . '</a>' ); } } } echo implode( ' ', $t_items ); if( $t_last_page < $p_end ) { print( ' ... ' ); } # Next and Last links echo ' '; if( $p_current < $p_end ) { print_page_link( $p_page, $t_next, $p_current + 1, $p_current, $p_temp_filter_id ); } else { print_page_link( $p_page, $t_next, null, null, $p_temp_filter_id ); } echo ' '; print_page_link( $p_page, $t_last, $p_end, $p_current, $p_temp_filter_id ); print( ' ]' ); } /** * print a mailto: href link * * @param string $p_email Email Address. * @param string $p_text Link text to display to user. * @return void */ function print_email_link( $p_email, $p_text ) { echo get_email_link( $p_email, $p_text ); } /** * return the mailto: href string link instead of printing it * * @param string $p_email Email Address. * @param string $p_text Link text to display to user. * @return string */ function get_email_link( $p_email, $p_text ) { return prepare_email_link( $p_email, $p_text ); } /** * print a mailto: href link with subject * * @param string $p_email Email Address. * @param string $p_text Link text to display to user. * @param string $p_bug_id The bug identifier. * @return void */ function print_email_link_with_subject( $p_email, $p_text, $p_bug_id ) { $t_bug = bug_get( $p_bug_id, true ); if( !access_has_project_level( config_get( 'show_user_email_threshold', null, null, $t_bug->project_id ), $t_bug->project_id ) ) { echo $p_text; return; } $t_subject = email_build_subject( $p_bug_id ); echo get_email_link_with_subject( $p_email, $p_text, $t_subject ); } /** * return the mailto: href string link instead of printing it * add subject line * * @param string $p_email Email Address. * @param string $p_text Link text to display to user. * @param string $p_subject Email subject line. * @return string */ function get_email_link_with_subject( $p_email, $p_text, $p_subject ) { # If we apply string_url() to the whole mailto: link then the @ # gets turned into a %40 and you can't right click in browsers to # do Copy Email Address. If we don't apply string_url() to the # subject text then an ampersand (for example) will truncate the text $t_subject = string_url( $p_subject ); $t_email = string_url( $p_email ); $t_mailto = string_attribute( 'mailto:' . $t_email . '?subject=' . $t_subject ); $t_text = string_display( $p_text ); return '<a class="user" href="' . $t_mailto . '">' . $t_text . '</a>'; } /** * Print a hidden input for each name=>value pair in the array * * If a value is an array an input will be created for each item with a name * that ends with [] * The names and values are passed through htmlspecialchars() before being displayed * * @param array $p_assoc_array Array of Name/Value pairs for html input tags. * @return void */ function print_hidden_inputs( array $p_assoc_array ) { foreach( $p_assoc_array as $t_key => $t_val ) { print_hidden_input( $t_key, $t_val ); } } /** * Print hidden html input tag <input type=hidden> * * @param string $p_field_key Name parameter. * @param string $p_field_val Value parameter. * @return void */ function print_hidden_input( $p_field_key, $p_field_val ) { if( is_array( $p_field_val ) ) { foreach( $p_field_val as $t_key => $t_value ) { if( is_array( $t_value ) ) { $t_key = string_html_entities( $t_key ); $t_field_key = $p_field_key . '[' . $t_key . ']'; print_hidden_input( $t_field_key, $t_value ); } else { $t_field_key = $p_field_key . '[' . $t_key . ']'; print_hidden_input( $t_field_key, $t_value ); } } } else { $t_key = string_html_entities( $p_field_key ); $t_val = string_html_entities( $p_field_val ); echo '<input type="hidden" name="' . $t_key . '" value="' . $t_val . '" />' . "\n"; } } /** * This prints the little [?] link for user help * @param string $p_a_name The anchor to use when accessing the documentation. * @return void */ function print_documentation_link( $p_a_name = '' ) { echo lang_get( $p_a_name ); # @todo Disable documentation links for now. May be re-enabled if linked to new manual. # echo "<a href=\"doc/documentation.html#$p_a_name\" target=\"_info\">[?]</a>"; } /** * prints the sign up link * @return void */ function print_signup_link() { if( ( ON == config_get_global( 'allow_signup' ) ) && ( LDAP != config_get_global( 'login_method' ) ) && ( ON == config_get( 'enable_email_notification' ) ) ) { print_bracket_link( 'signup_page.php', lang_get( 'signup_link' ) ); } } /** * prints the login link * @return void */ function print_login_link() { print_bracket_link( 'login_page.php', lang_get( 'login_title' ) ); } /** * prints the lost password link * @return void */ function print_lost_password_link() { # lost password feature disabled or reset password via email disabled -> stop here! if( ( LDAP != config_get_global( 'login_method' ) ) && ( ON == config_get( 'lost_password_feature' ) ) && ( ON == config_get( 'send_reset_password' ) ) && ( ON == config_get( 'enable_email_notification' ) ) ) { print_bracket_link( 'lost_pwd_page.php', lang_get( 'lost_password_link' ) ); } } /** * Get icon corresponding to the specified filename * * @param string $p_filename Filename for which to retrieve icon link. * @return void */ function print_file_icon( $p_filename ) { $t_icon = file_get_icon_url( $p_filename ); echo '<img src="' . string_attribute( $t_icon['url'] ) . '" alt="' . string_attribute( $t_icon['alt'] ) . ' file icon" width="16" height="16" />'; } /** * Prints an RSS image that is hyperlinked to an RSS feed. * * @param string $p_feed_url URI to an RSS feed. * @param string $p_title Title to use for hyperlink. * @return void */ function print_rss( $p_feed_url, $p_title = '' ) { $t_path = config_get( 'path' ); echo '<a class="rss" rel="alternate" href="', htmlspecialchars( $p_feed_url ), '" title="', $p_title, '"><img src="', $t_path, '/images/', 'rss.png" width="16" height="16" alt="', $p_title, '" /></a>'; } /** * Prints the recently visited issues. * @return void */ function print_recently_visited() { $t_ids = last_visited_get_array(); if( count( $t_ids ) == 0 ) { return; } echo '<div class="recently-visited">' . lang_get( 'recently_visited' ) . ': '; $t_first = true; foreach( $t_ids as $t_id ) { if( !$t_first ) { echo ', '; } else { $t_first = false; } echo string_get_bug_view_link( $t_id ); } echo '</div>'; } /** * print a drop down box from input array * @param array $p_control_array Array of elements in drop down list (name, description). * @param string $p_control_name Name attribute of <select> box. * @param string|array $p_match Either a string or an array of selected values. * @param boolean $p_add_any Whether to display an '[any]' option in the drop down. * @param boolean $p_multiple Whether drop down list allows multiple values to be selected. * @return string */ function get_dropdown( array $p_control_array, $p_control_name, $p_match = '', $p_add_any = false, $p_multiple = false ) { if( $p_multiple ) { $t_size = ' size="5"'; $t_multiple = ' multiple="multiple"'; } else { $t_size = ''; $t_multiple = ''; } $t_info = sprintf( '<select %s name="%s" id="%s"%s>', $t_multiple, $p_control_name, $p_control_name, $t_size ); if( $p_add_any ) { array_unshift_assoc( $p_control_array, META_FILTER_ANY, lang_trans( '[any]' ) ); } while( list( $t_name, $t_desc ) = each( $p_control_array ) ) { $t_sel = ''; if( is_array( $p_match ) ) { if( in_array( $t_name, array_values( $p_match ) ) || in_array( $t_desc, array_values( $p_match ) ) ) { $t_sel = ' selected="selected"'; } } else { if( ( $t_name === $p_match ) || ( $t_desc === $p_match ) ) { $t_sel = ' selected="selected"'; } } $t_info .= sprintf( '<option%s value="%s">%s</option>', $t_sel, $t_name, $t_desc ); } $t_info .= "</select>\n"; return $t_info; } /** * Prints the list of visible attachments belonging to a given bug. * @param integer $p_bug_id ID of the bug to print attachments list for. * @return void */ function print_bug_attachments_list( $p_bug_id ) { $t_attachments = file_get_visible_attachments( $p_bug_id ); echo "\n<ul>"; foreach ( $t_attachments as $t_attachment ) { echo "\n<li>"; print_bug_attachment( $t_attachment ); echo "\n</li>"; } echo "\n</ul>"; } /** * Prints information about a single attachment including download link, file * size, upload timestamp and an expandable preview for text and image file * types. * If $p_security_token is null, a token will be generated with form_security_token(). * If otherwise specified (i.e. not null), the parameter must contain * a valid security token, previously generated by form_security_token(). * Use this to avoid performance issues when loading pages having many calls to * this function, such as print_bug_attachments_list(). * @param array $p_attachment An attachment array from within the array returned by the file_get_visible_attachments() function. * @param mixed $p_security_token Optional; null (default) or security token string. * @see form_security_token() * @return void */ function print_bug_attachment( array $p_attachment, $p_security_token = null ) { $t_show_attachment_preview = $p_attachment['preview'] && $p_attachment['exists'] && ( $p_attachment['type'] == 'text' || $p_attachment['type'] == 'image' ); if( $t_show_attachment_preview ) { $t_collapse_id = 'attachment_preview_' . $p_attachment['id']; global $g_collapse_cache_token; $g_collapse_cache_token[$t_collapse_id] = false; collapse_open( $t_collapse_id ); } # The same token is used for both links in the collapse section if( null === $p_security_token ) { $p_security_token = form_security_token( 'bug_file_delete' ); } print_bug_attachment_header( $p_attachment, $p_security_token ); if( $t_show_attachment_preview ) { echo lang_get( 'word_separator' ); collapse_icon( $t_collapse_id ); if( $p_attachment['type'] == 'text' ) { print_bug_attachment_preview_text( $p_attachment ); } else if( $p_attachment['type'] === 'image' ) { print_bug_attachment_preview_image( $p_attachment ); } collapse_closed( $t_collapse_id ); print_bug_attachment_header( $p_attachment, $p_security_token ); echo lang_get( 'word_separator' ); collapse_icon( $t_collapse_id ); collapse_end( $t_collapse_id ); } } /** * Prints a single textual line of information about an attachment including download link, file * size and upload timestamp. * If $p_security_token is null, a token will be generated with form_security_token(). * If otherwise specified (i.e. not null), the parameter must contain * a valid security token, previously generated by form_security_token(). * Use this to avoid performance issues when loading pages having many calls to * this function, such as print_bug_attachments_list(). * @param array $p_attachment An attachment array from within the array returned by the file_get_visible_attachments() function. * @param mixed $p_security_token Optional; null (default) or security token string. * @see form_security_token() * @return void */ function print_bug_attachment_header( array $p_attachment, $p_security_token = null ) { echo "\n"; if( $p_attachment['exists'] ) { if( $p_attachment['can_download'] ) { echo '<a href="' . string_attribute( $p_attachment['download_url'] ) . '">'; } print_file_icon( $p_attachment['display_name'] ); if( $p_attachment['can_download'] ) { echo '</a>'; } echo lang_get( 'word_separator' ); if( $p_attachment['can_download'] ) { echo '<a href="' . string_attribute( $p_attachment['download_url'] ) . '">'; } echo string_display_line( $p_attachment['display_name'] ); if( $p_attachment['can_download'] ) { echo '</a>'; } echo lang_get( 'word_separator' ) . '(' . number_format( $p_attachment['size'] ) . lang_get( 'word_separator' ) . lang_get( 'bytes' ) . ')'; echo lang_get( 'word_separator' ) . '<span class="italic">' . date( config_get( 'normal_date_format' ), $p_attachment['date_added'] ) . '</span>'; event_signal( 'EVENT_VIEW_BUG_ATTACHMENT', array( $p_attachment ) ); } else { print_file_icon( $p_attachment['display_name'] ); echo lang_get( 'word_separator' ) . '<span class="strike">' . string_display_line( $p_attachment['display_name'] ) . '</span>' . lang_get( 'word_separator' ) . '(' . lang_get( 'attachment_missing' ) . ')'; } if( $p_attachment['can_delete'] ) { echo lang_get( 'word_separator' ) . '['; print_link( 'bug_file_delete.php?file_id=' . $p_attachment['id'] . form_security_param( 'bug_file_delete', $p_security_token ), lang_get( 'delete_link' ), false, 'small' ); echo ']'; } } /** * Prints the preview of a text file attachment. * @param array $p_attachment An attachment array from within the array returned by the file_get_visible_attachments() function. * @return void */ function print_bug_attachment_preview_text( array $p_attachment ) { if( !$p_attachment['exists'] ) { return; } echo "\n<pre class=\"bug-attachment-preview-text\">"; switch( config_get( 'file_upload_method' ) ) { case DISK: if( file_exists( $p_attachment['diskfile'] ) ) { $t_content = file_get_contents( $p_attachment['diskfile'] ); } break; case DATABASE: db_param_push(); $t_query = 'SELECT * FROM {bug_file} WHERE id=' . db_param(); $t_result = db_query( $t_query, array( (int)$p_attachment['id'] ) ); $t_row = db_fetch_array( $t_result ); $t_content = $t_row['content']; break; default: trigger_error( ERROR_GENERIC, ERROR ); } echo htmlspecialchars( $t_content ); echo '</pre>'; } /** * Prints the preview of an image file attachment. * @param array $p_attachment An attachment array from within the array returned by the file_get_visible_attachments() function. * @return void */ function print_bug_attachment_preview_image( array $p_attachment ) { $t_preview_style = 'border: 0;'; $t_max_width = config_get( 'preview_max_width' ); if( $t_max_width > 0 ) { $t_preview_style .= ' max-width:' . $t_max_width . 'px;'; } $t_max_height = config_get( 'preview_max_height' ); if( $t_max_height > 0 ) { $t_preview_style .= ' max-height:' . $t_max_height . 'px;'; } $t_title = file_get_field( $p_attachment['id'], 'title' ); $t_image_url = $p_attachment['download_url'] . '&show_inline=1' . form_security_param( 'file_show_inline' ); echo "\n<div class=\"bug-attachment-preview-image\">"; echo '<a href="' . string_attribute( $p_attachment['download_url'] ) . '">'; echo '<img src="' . string_attribute( $t_image_url ) . '" alt="' . string_attribute( $t_title ) . '" style="' . string_attribute( $t_preview_style ) . '" />'; echo '</a></div>'; } /** * Print the option list for time zones * @param string $p_timezone Selected time zone. * @return void */ function print_timezone_option_list( $p_timezone ) { $t_identifiers = timezone_identifiers_list( DateTimeZone::ALL ); foreach( $t_identifiers as $t_identifier ) { $t_zone = explode( '/', $t_identifier, 2 ); if( isset( $t_zone[1] ) ) { $t_id = $t_zone[1]; } else { $t_id = $t_identifier; } $t_locations[$t_zone[0]][$t_identifier] = array( str_replace( '_', ' ', $t_id ), $t_identifier ); } foreach( $t_locations as $t_continent => $t_locations ) { echo "\t" . '<optgroup label="' . $t_continent . '">' . "\n"; foreach ( $t_locations as $t_location ) { echo "\t\t" . '<option value="' . $t_location[1] . '"'; check_selected( $p_timezone, $t_location[1] ); echo '>' . $t_location[0] . '</option>' . "\n"; } echo "\t" . '</optgroup>' . "\n"; } } /** * Return file size information * @param integer $p_size File size. * @param string $p_unit File size unit. * @return string */ function get_filesize_info( $p_size, $p_unit ) { return sprintf( lang_get( 'file_size_info' ), number_format( $p_size ), $p_unit ); } /** * Print maximum file size information * @param integer $p_size Size in bytes. * @param integer $p_divider Optional divider, defaults to 1000. * @param string $p_unit Optional language string of unit, defaults to KB. * @return void */ function print_max_filesize( $p_size, $p_divider = 1000, $p_unit = 'kb' ) { echo '<span class="small" title="' . get_filesize_info( $p_size, lang_get( 'bytes' ) ) . '">'; echo lang_get( 'max_file_size_label' ) . lang_get( 'word_separator' ) . get_filesize_info( $p_size / $p_divider, lang_get( $p_unit ) ); echo '</span>'; } | ||||
duplicate of | 0004750 | new | Add option to sort product version alphabetically |