Example #1
0
/**
 * Parse a workflow into a graph-like array of workflow transitions.
 * @param array The workflow enumeration to parse.
 * @return array The parsed workflow graph.
 */
function workflow_parse($p_enum_workflow)
{
    $t_status_arr = MantisEnum::getAssocArrayIndexedByValues(config_get('status_enum_string'));
    if (count($p_enum_workflow) == 0) {
        # workflow is not set, default it to all transitions
        foreach ($t_status_arr as $t_status => $t_label) {
            $t_temp_workflow = array();
            foreach ($t_status_arr as $t_next => $t_next_label) {
                if ($t_status != $t_next) {
                    $t_temp_workflow[] = $t_next . ':' . $t_next_label;
                }
            }
            $p_enum_workflow[$t_status] = implode(',', $t_temp_workflow);
        }
    }
    $t_entry = array();
    $t_exit = array();
    # prepopulate new bug state (bugs go from nothing to here)
    $t_submit_status_array = config_get('bug_submit_status');
    $t_new_label = MantisEnum::getLabel(lang_get('status_enum_string'), config_get('bug_submit_status'));
    if (is_array($t_submit_status_array)) {
        # @@@ (thraxisp) this is not implemented in bug_api.php
        foreach ($t_submit_status_array as $t_access => $t_status) {
            $t_entry[$t_status][0] = $t_new_label;
            $t_exit[0][$t_status] = $t_new_label;
        }
    } else {
        $t_status = $t_submit_status_array;
        $t_entry[$t_status][0] = $t_new_label;
        $t_exit[0][$t_status] = $t_new_label;
    }
    # add user defined arcs and implicit reopen arcs
    $t_reopen = config_get('bug_reopen_status');
    $t_reopen_label = MantisEnum::getLabel(lang_get('resolution_enum_string'), config_get('bug_reopen_resolution'));
    $t_resolved_status = config_get('bug_resolved_status_threshold');
    $t_default = array();
    foreach ($t_status_arr as $t_status => $t_status_label) {
        if (isset($p_enum_workflow[$t_status])) {
            $t_next_arr = MantisEnum::getAssocArrayIndexedByValues($p_enum_workflow[$t_status]);
            foreach ($t_next_arr as $t_next => $t_next_label) {
                if (!isset($t_default[$t_status])) {
                    $t_default[$t_status] = $t_next;
                }
                $t_exit[$t_status][$t_next] = '';
                $t_entry[$t_next][$t_status] = '';
            }
        } else {
            $t_exit[$t_status] = array();
        }
        if ($t_status >= $t_resolved_status) {
            $t_exit[$t_status][$t_reopen] = $t_reopen_label;
            $t_entry[$t_reopen][$t_status] = $t_reopen_label;
        }
        if (!isset($t_entry[$t_status])) {
            $t_entry[$t_status] = array();
        }
    }
    return array('entry' => $t_entry, 'exit' => $t_exit, 'default' => $t_default);
}
function reminder_print_status_option_list($p_name)
{
    $t_enum_values = MantisEnum::getValues(config_get('status_enum_string'));
    $t_selection = plugin_config_get($p_name);
    echo '<select name="' . $p_name . '[]" multiple="multiple" size="' . count($t_enum_values) . '">';
    foreach ($t_enum_values as $t_key) {
        $t_elem2 = get_enum_element('status', $t_key);
        echo '<option value="' . $t_key . '"';
        reminder_check_selected($t_selection, $t_key);
        echo '>' . $t_elem2 . '</option>';
    }
    echo '</select>';
}
/**
 * Print table head
 * @param $status_cols
 */
function print_thead($status_cols)
{
    echo '<thead>';
    echo '<tr>';
    echo '<th></th>';
    foreach ($status_cols as $status_col) {
        echo '<th bgcolor="' . get_status_color($status_col, null, null) . '" class="center">';
        $assocArray = MantisEnum::getAssocArrayIndexedByValues(lang_get('status_enum_string'));
        echo $assocArray[$status_col];
        echo '</th>';
    }
    echo '</tr>';
    echo '</thead>';
}
Example #4
0
/**
 * Return html for a row
 * @param string  $p_caption      Caption.
 * @param integer $p_access_level Access level.
 * @return string
 */
function get_capability_row($p_caption, $p_access_level)
{
    $t_access_levels = MantisEnum::getValues(config_get('access_levels_enum_string'));
    $t_output = '<tr><td>' . string_display($p_caption) . '</td>';
    foreach ($t_access_levels as $t_access_level) {
        if ($t_access_level >= (int) $p_access_level) {
            $t_value = '<img src="images/ok.gif" width="20" height="15" alt="X" title="X" />';
        } else {
            $t_value = '&#160;';
        }
        $t_output .= '<td class="center">' . $t_value . '</td>';
    }
    $t_output .= '</tr>' . "\n";
    return $t_output;
}
function set_capability_row( $p_threshold, $p_all_projects_only=false ) {
	global $t_access, $t_project;

	if ( ( $t_access >= config_get_access( $p_threshold ) )
			  && ( ( ALL_PROJECTS == $t_project ) || !$p_all_projects_only ) ) {
		$f_threshold = gpc_get_int_array( 'flag_thres_' . $p_threshold, array() );
		$f_access = gpc_get_int( 'access_' . $p_threshold );
		# @@debug @@ echo "<br />for $p_threshold "; var_dump($f_threshold, $f_access); echo '<br />';
		$t_access_levels = MantisEnum::getAssocArrayIndexedByValues( config_get( 'access_levels_enum_string' ) );
		ksort( $t_access_levels );
		reset( $t_access_levels );

		$t_lower_threshold = NOBODY;
		$t_array_threshold = array();

		foreach( $t_access_levels as $t_access_level => $t_level_name ) {
			if ( in_array( $t_access_level, $f_threshold ) ) {
				if ( NOBODY == $t_lower_threshold ) {
					$t_lower_threshold = $t_access_level;
				}
				$t_array_threshold[] = $t_access_level;
			} else {
				if ( NOBODY <> $t_lower_threshold ) {
					$t_lower_threshold = -1;
				}
			}
		# @@debug @@ var_dump($$t_access_level, $t_lower_threshold, $t_array_threshold); echo '<br />';
		}
		$t_existing_threshold = config_get( $p_threshold );
		$t_existing_access = config_get_access( $p_threshold );
		if ( -1 == $t_lower_threshold ) {
			if ( ( $t_existing_threshold != $t_array_threshold )
					|| ( $t_existing_access != $f_access ) ) {
				config_set( $p_threshold, $t_array_threshold, NO_USER, $t_project, $f_access );
			}
		} else {
			if ( ( $t_existing_threshold != $t_lower_threshold )
					|| ( $t_existing_access != $f_access ) ) {
				config_set( $p_threshold, $t_lower_threshold, NO_USER, $t_project, $f_access );
			}
		}
	}
}
function get_status_option_list_plugin($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);
    $t_enum_values = MantisEnum::getValues($t_config_var_value);
    $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;
}
 function renderLists()
 {
     $content = '';
     $status_codes = config_get('status_enum_string');
     $t_status_array = MantisEnum::getAssocArrayIndexedByValues($status_codes);
     foreach ($t_status_array as $status => $statusCode) {
         if ($statusCode != "backlog" && $statusCode != "closed") {
             $issues = $this->renderIssues($status);
             $statusName = string_display_line(get_enum_element('status', $status));
             $content .= '<div class="column">
                                 <div class="inside"
                                 style="background-color: ' . get_status_color($status) . '"
                                 id="' . $status . '">
                                 <h5 title="' . $status . '">' . $statusName . ' (' . sizeof($issues) . ')</h5>';
             $content .= implode("\n", $issues);
             $content .= '</div>';
             // inside
             $content .= '</div>';
             // column
         }
     }
     return $content;
 }
function getBugsInfoJSONPResponse($bugsString)
{
    $t_bug_table = db_get_table('mantis_bug_table');
    $t_statuses = MantisEnum::getAssocArrayIndexedByValues(config_get('status_enum_string'));
    $statuses = '';
    foreach ($t_statuses as $t_state => $t_label) {
        $statuses .= '"' . $t_label . '": "' . get_status_color($t_state) . '", ';
    }
    $bugs_list = array_unique(str_split($bugsString, 7));
    $bugs_list = "'" . implode("', '", $bugs_list) . "'";
    $query = "SELECT id, status, summary\r\n\t\t\t  FROM `" . $t_bug_table . "`\r\n\t\t\t  WHERE id IN (" . $bugs_list . ")\r\n\t\t\t  ORDER BY FIELD(id, " . $bugs_list . ")";
    $results = db_query_bound($query);
    if ($results) {
        $json = '';
        while ($row = db_fetch_array($results)) {
            $id = $row['id'];
            $statusId = $row['status'];
            $summary = $row['summary'];
            $json .= '"' . $id . '": { "status": "' . $t_statuses[$statusId] . '", "summary": "' . htmlspecialchars($summary) . '" }, ';
        }
    }
    header("Content-Type: application/javascript; charset=utf-8");
    echo 'bugtrackerConnection_callback( { "offset": "' . $_REQUEST['offset'] . '", "length": "' . $_REQUEST['length'] . '", "statuses": { ' . substr($statuses, 0, -2) . ' }, "bugsInfo" : { ' . substr($json, 0, -2) . ' } } );';
}
Example #9
0
if ($t_resolve_issue) {
    email_resolved($f_bug_id);
    email_relationship_child_resolved($f_bug_id);
} else {
    if ($t_close_issue) {
        email_close($f_bug_id);
        email_relationship_child_closed($f_bug_id);
    } else {
        if ($t_reopen_issue) {
            email_reopen($f_bug_id);
        } else {
            if ($t_existing_bug->handler_id === NO_USER && $t_updated_bug->handler_id !== NO_USER) {
                email_assign($f_bug_id);
            } else {
                if ($t_existing_bug->status !== $t_updated_bug->status) {
                    $t_new_status_label = MantisEnum::getLabel(config_get('status_enum_string'), $t_updated_bug->status);
                    $t_new_status_label = str_replace(' ', '_', $t_new_status_label);
                    email_generic($f_bug_id, $t_new_status_label, 'email_notification_title_for_status_bug_' . $t_new_status_label);
                } else {
                    email_generic($f_bug_id, 'updated', 'email_notification_title_for_action_bug_updated');
                }
            }
        }
    }
}
# Twitter notification of bug update.
if ($t_resolve_issue && $t_updated_bug->resolution >= config_get('bug_resolution_fixed_threshold') && $t_updated_bug->resolution < config_get('bug_resolution_not_fixed_threshold')) {
    twitter_issue_resolved($f_bug_id);
}
form_security_purge('bug_update');
print_successful_redirect_to_bug($f_bug_id);
Example #10
0
/**
 * Given a enum string and num, return the appropriate localized string
 * @param string $p_enum_name Enumeration name.
 * @param string $p_val       Enumeration value.
 * @param string $p_lang      Language string.
 * @return string
 */
function mci_get_enum_element($p_enum_name, $p_val, $p_lang)
{
    $t_enum_string = config_get($p_enum_name . '_enum_string');
    $t_localized_enum_string = lang_get($p_enum_name . '_enum_string', $p_lang);
    return MantisEnum::getLocalizedLabel($t_enum_string, $t_localized_enum_string, $p_val);
}
Example #11
0
function enum_bug_group($p_enum_string, $p_enum)
{
    $t_bug_table = db_get_table('bug');
    $t_project_id = helper_get_current_project();
    $t_bug_table = db_get_table('bug');
    $t_user_id = auth_get_current_user_id();
    $t_res_val = config_get('bug_resolved_status_threshold');
    $t_clo_val = config_get('bug_closed_status_threshold');
    $specific_where = " AND " . helper_project_specific_where($t_project_id, $t_user_id);
    $t_array_indexed_by_enum_values = MantisEnum::getAssocArrayIndexedByValues($p_enum_string);
    $enum_count = count($t_array_indexed_by_enum_values);
    foreach ($t_array_indexed_by_enum_values as $t_value => $t_label) {
        # Calculates the number of bugs opened and puts the results in a table
        $query = "SELECT COUNT(*)\n\t\t\t\t\tFROM {$t_bug_table}\n\t\t\t\t\tWHERE {$p_enum}='{$t_value}' AND\n\t\t\t\t\t\tstatus<'{$t_res_val}' {$specific_where}";
        $result2 = db_query($query);
        $t_metrics['open'][$t_label] = db_result($result2, 0, 0);
        # Calculates the number of bugs closed and puts the results in a table
        $query = "SELECT COUNT(*)\n\t\t\t\t\tFROM {$t_bug_table}\n\t\t\t\t\tWHERE {$p_enum}='{$t_value}' AND\n\t\t\t\t\t\tstatus='{$t_clo_val}' {$specific_where}";
        $result2 = db_query($query);
        $t_metrics['closed'][$t_label] = db_result($result2, 0, 0);
        # Calculates the number of bugs resolved and puts the results in a table
        $query = "SELECT COUNT(*)\n\t\t\t\t\tFROM {$t_bug_table}\n\t\t\t\t\tWHERE {$p_enum}='{$t_value}' AND\n\t\t\t\t\t\tstatus>='{$t_res_val}'  AND\n\t\t\t\t\t\tstatus<'{$t_clo_val}' {$specific_where}";
        $result2 = db_query($query);
        $t_metrics['resolved'][$t_label] = db_result($result2, 0, 0);
    }
    # ## end for
    return $t_metrics;
}
Example #12
0
/**
 * Given a enum string and num, return the appropriate string for the
 * specified user/project
 * @param string $p_enum_name
 * @param int $p_val
 * @param int|null $p_user user id, defaults to null (all users)
 * @param int|null $p_project project id, defaults to null (all projects)
 * @return string
 */
function get_enum_element($p_enum_name, $p_val, $p_user = null, $p_project = null)
{
    $config_var = config_get($p_enum_name . '_enum_string', null, $p_user, $p_project);
    $string_var = lang_get($p_enum_name . '_enum_string');
    return MantisEnum::getLocalizedLabel($config_var, $string_var, $p_val);
}
Example #13
0
    // no data to graph
    exit;
}
$t_bug_table = db_get_table('mantis_bug_table');
$t_bug_hist_table = db_get_table('mantis_bug_history_table');
$t_marker = array();
$t_data = array();
$t_ptr = 0;
$t_end = $t_interval->get_end_timestamp();
$t_start = $t_interval->get_start_timestamp();
if ($t_end == false || $t_start == false) {
    return;
}
// grab all status levels
$t_status_arr = MantisEnum::getAssocArrayIndexedByValues(config_get('status_enum_string'));
$t_status_labels = MantisEnum::getAssocArrayIndexedByValues(lang_get('status_enum_string'));
$t_default_bug_status = config_get('bug_submit_status');
$t_bug = array();
$t_view_status = array();
// walk through all issues and grab their status for 'now'
$t_marker[$t_ptr] = time();
foreach ($rows as $t_row) {
    if (isset($t_data[$t_ptr][$t_row->status])) {
        $t_data[$t_ptr][$t_row->status]++;
    } else {
        $t_data[$t_ptr][$t_row->status] = 1;
        $t_view_status[$t_row->status] = isset($t_status_arr[$t_row->status]) ? $t_status_arr[$t_row->status] : '@' . $t_row->status . '@';
    }
    $t_bug[] = $t_row->id;
}
// get the history for these bugs over the interval required to offset the data
/**
 * Get the enum id given the enum label.
 *
 * @param $p_enum_string   The enum string to search in.
 * @param $p_label         The label to search for.
 *
 * @return The id corresponding to the given label, or 0 if not found.
 */
function mci_get_enum_value_from_label($p_enum_string, $p_label)
{
    $t_value = MantisEnum::getValue($p_enum_string, $p_label);
    if ($t_value === false) {
        return 0;
    }
    return $t_value;
}
<!-- Access Level -->
<tr <?php 
echo helper_alternate_class();
?>
>
	<td class="category">
		<?php 
echo lang_get('access_level');
?>
	</td>
	<td>
		<select name="access_level">
			<?php 
$t_access_level = $t_user['access_level'];
if (!MantisEnum::hasValue(config_get('access_levels_enum_string'), $t_access_level)) {
    $t_access_level = config_get('default_new_account_access_level');
}
print_project_access_levels_option_list($t_access_level);
?>
		</select>
	</td>
</tr>

<!-- Enabled Checkbox -->
<tr <?php 
echo helper_alternate_class();
?>
>
	<td class="category">
		<?php 
/**
 * access row
 * @return void
 */
function access_row()
{
    global $g_access, $g_can_change_flags;
    $t_enum_status = MantisEnum::getAssocArrayIndexedByValues(config_get('status_enum_string'));
    $t_file_new = config_get_global('report_bug_threshold');
    $t_global_new = config_get('report_bug_threshold', null, ALL_USERS, ALL_PROJECTS);
    $t_project_new = config_get('report_bug_threshold');
    $t_file_set = config_get_global('set_status_threshold');
    $t_global_set = config_get('set_status_threshold', null, ALL_USERS, ALL_PROJECTS);
    $t_project_set = config_get('set_status_threshold');
    $t_submit_status = config_get('bug_submit_status');
    # Print the table rows
    foreach ($t_enum_status as $t_status => $t_status_label) {
        echo "\t\t" . '<tr><td class="width30">' . string_no_break(MantisEnum::getLabel(lang_get('status_enum_string'), $t_status)) . '</td>' . "\n";
        if ($t_status == $t_submit_status) {
            # 'NEW' status
            $t_level_project = $t_project_new;
            $t_can_change = $g_access >= config_get_access('report_bug_threshold');
            $t_color = set_color_override($t_file_new, $t_global_new, $t_project_new);
            set_overrides('report_bug_threshold', $t_can_change, $t_color);
        } else {
            # Other statuses
            # File level: fallback if set_status_threshold is not defined
            if (isset($t_file_set[$t_status])) {
                $t_level_file = $t_file_set[$t_status];
            } else {
                $t_level_file = config_get_global('update_bug_status_threshold');
            }
            $t_level_global = isset($t_global_set[$t_status]) ? $t_global_set[$t_status] : $t_level_file;
            $t_level_project = isset($t_project_set[$t_status]) ? $t_project_set[$t_status] : $t_level_global;
            $t_can_change = $g_access >= config_get_access('set_status_threshold');
            $t_color = set_color_override($t_level_file, $t_level_global, $t_level_project);
            set_overrides('set_status_threshold', $t_can_change, $t_color);
        }
        if ($t_can_change) {
            echo '<td class="center ' . $t_color . '"><select name="access_change_' . $t_status . '">' . "\n";
            print_enum_string_option_list('access_levels', $t_level_project);
            echo '</select> </td>' . "\n";
            $g_can_change_flags = true;
        } else {
            echo '<td class="center ' . $t_color . '">' . MantisEnum::getLabel(lang_get('access_levels_enum_string'), $t_level_project) . '</td>' . "\n";
        }
        echo '</tr>' . "\n";
    }
}
Example #17
0
/**
 * Print reporter effectiveness report
 *
 * @param string $p_severity_enum_string   Severity enumeration string.
 * @param string $p_resolution_enum_string Resolution enumeration string.
 * @return void
 */
function summary_print_reporter_effectiveness($p_severity_enum_string, $p_resolution_enum_string)
{
    $t_reporter_summary_limit = config_get('reporter_summary_limit');
    $t_project_id = helper_get_current_project();
    $t_severity_multipliers = config_get('severity_multipliers');
    $t_resolution_multipliers = config_get('resolution_multipliers');
    # Get the severity values to use
    $c_sev_s = MantisEnum::getValues($p_severity_enum_string);
    $t_enum_sev_count = count($c_sev_s);
    # Get the resolution values to use
    $c_res_s = MantisEnum::getValues($p_resolution_enum_string);
    # Checking if it's a per project statistic or all projects
    $t_specific_where = helper_project_specific_where($t_project_id);
    if (' 1<>1' == $t_specific_where) {
        return;
    }
    # Get all of the bugs and split them up into an array
    $t_query = 'SELECT COUNT(id) as bugcount, reporter_id, resolution, severity
				FROM {bug}
				WHERE ' . $t_specific_where . '
				GROUP BY reporter_id, resolution, severity';
    $t_result = db_query($t_query);
    $t_reporter_ressev_arr = array();
    $t_reporter_bugcount_arr = array();
    $t_arr = db_fetch_array($t_result);
    while ($t_arr) {
        if (!isset($t_reporter_ressev_arr[$t_arr['reporter_id']])) {
            $t_reporter_ressev_arr[$t_arr['reporter_id']] = array();
            $t_reporter_bugcount_arr[$t_arr['reporter_id']] = 0;
        }
        if (!isset($t_reporter_ressev_arr[$t_arr['reporter_id']][$t_arr['severity']])) {
            $t_reporter_ressev_arr[$t_arr['reporter_id']][$t_arr['severity']] = array();
            $t_reporter_ressev_arr[$t_arr['reporter_id']][$t_arr['severity']]['total'] = 0;
        }
        if (!isset($t_reporter_ressev_arr[$t_arr['reporter_id']][$t_arr['severity']][$t_arr['resolution']])) {
            $t_reporter_ressev_arr[$t_arr['reporter_id']][$t_arr['severity']][$t_arr['resolution']] = 0;
        }
        $t_reporter_ressev_arr[$t_arr['reporter_id']][$t_arr['severity']][$t_arr['resolution']] += $t_arr['bugcount'];
        $t_reporter_ressev_arr[$t_arr['reporter_id']][$t_arr['severity']]['total'] += $t_arr['bugcount'];
        $t_reporter_bugcount_arr[$t_arr['reporter_id']] += $t_arr['bugcount'];
        $t_arr = db_fetch_array($t_result);
    }
    # Sort our total bug count array so that the reporters with the highest number of bugs are listed first,
    arsort($t_reporter_bugcount_arr);
    $t_row_count = 0;
    # We now have a multi dimensional array of users, resolutions and severities, with the
    # value of each resolution and severity for each user
    foreach ($t_reporter_bugcount_arr as $t_reporter_id => $t_total_user_bugs) {
        # Limit the number of reporters listed
        if ($t_row_count > $t_reporter_summary_limit) {
            break;
        }
        # Only print reporters who have reported at least one bug. This helps
        # prevent divide by zeroes, showing reporters not on this project, and showing
        # users that aren't actually reporters...
        if ($t_total_user_bugs > 0) {
            $t_arr2 = $t_reporter_ressev_arr[$t_reporter_id];
            echo '<tr>';
            $t_row_count++;
            echo '<td>';
            echo string_display_line(user_get_name($t_reporter_id));
            echo '</td>';
            $t_total_severity = 0;
            $t_total_errors = 0;
            for ($j = 0; $j < $t_enum_sev_count; $j++) {
                if (!isset($t_arr2[$c_sev_s[$j]])) {
                    continue;
                }
                $t_sev_bug_count = $t_arr2[$c_sev_s[$j]]['total'];
                $t_sev_mult = 1;
                if ($t_severity_multipliers[$c_sev_s[$j]]) {
                    $t_sev_mult = $t_severity_multipliers[$c_sev_s[$j]];
                }
                if ($t_sev_bug_count > 0) {
                    $t_total_severity += $t_sev_bug_count * $t_sev_mult;
                }
                foreach ($t_resolution_multipliers as $t_res => $t_res_mult) {
                    if (isset($t_arr2[$c_sev_s[$j]][$t_res])) {
                        $t_total_errors += $t_sev_mult * $t_res_mult;
                    }
                }
            }
            echo '<td class="right">' . $t_total_severity . '</td>';
            echo '<td class="right">' . $t_total_errors . '</td>';
            printf('<td class="right">%d</td>', $t_total_severity - $t_total_errors);
            echo '</tr>';
        }
    }
}
 /**
  * Update a bug from the given data structure
  *  If the third parameter is true, also update the longer strings table
  * @param bool p_update_extended
  * @param bool p_bypass_email Default false, set to true to avoid generating emails (if sending elsewhere)
  * @return bool (always true)
  * @access public
  */
 function update($p_update_extended = false, $p_bypass_mail = false)
 {
     self::validate($p_update_extended);
     $c_bug_id = $this->id;
     if (is_blank($this->due_date)) {
         $this->due_date = date_get_null();
     }
     $t_old_data = bug_get($this->id, true);
     $t_bug_table = db_get_table('mantis_bug_table');
     # Update all fields
     # Ignore date_submitted and last_updated since they are pulled out
     #  as unix timestamps which could confuse the history log and they
     #  shouldn't get updated like this anyway.  If you really need to change
     #  them use bug_set_field()
     $query = "UPDATE {$t_bug_table}\n\t\t\t\t\tSET project_id=" . db_param() . ', reporter_id=' . db_param() . ",\n\t\t\t\t\t\thandler_id=" . db_param() . ', duplicate_id=' . db_param() . ",\n\t\t\t\t\t\tpriority=" . db_param() . ', severity=' . db_param() . ",\n\t\t\t\t\t\treproducibility=" . db_param() . ', status=' . db_param() . ",\n\t\t\t\t\t\tresolution=" . db_param() . ', projection=' . db_param() . ",\n\t\t\t\t\t\tcategory_id=" . db_param() . ', eta=' . db_param() . ",\n\t\t\t\t\t\tos=" . db_param() . ', os_build=' . db_param() . ",\n\t\t\t\t\t\tplatform=" . db_param() . ', version=' . db_param() . ",\n\t\t\t\t\t\tbuild=" . db_param() . ', fixed_in_version=' . db_param() . ',';
     $t_fields = array($this->project_id, $this->reporter_id, $this->handler_id, $this->duplicate_id, $this->priority, $this->severity, $this->reproducibility, $this->status, $this->resolution, $this->projection, $this->category_id, $this->eta, $this->os, $this->os_build, $this->platform, $this->version, $this->build, $this->fixed_in_version);
     $t_roadmap_updated = false;
     if (access_has_project_level(config_get('roadmap_update_threshold'))) {
         $query .= "\n\t\t\t\t\t\ttarget_version=" . db_param() . ",";
         $t_fields[] = $this->target_version;
         $t_roadmap_updated = true;
     }
     $query .= "\n\t\t\t\t\t\tview_state=" . db_param() . ",\n\t\t\t\t\t\tsummary=" . db_param() . ",\n\t\t\t\t\t\tsponsorship_total=" . db_param() . ",\n\t\t\t\t\t\tsticky=" . db_param() . ",\n\t\t\t\t\t\tdue_date=" . db_param() . "\n\t\t\t\t\tWHERE id=" . db_param();
     $t_fields[] = $this->view_state;
     $t_fields[] = $this->summary;
     $t_fields[] = $this->sponsorship_total;
     $t_fields[] = (bool) $this->sticky;
     $t_fields[] = $this->due_date;
     $t_fields[] = $this->id;
     db_query_bound($query, $t_fields);
     bug_clear_cache($this->id);
     # log changes
     history_log_event_direct($c_bug_id, 'project_id', $t_old_data->project_id, $this->project_id);
     history_log_event_direct($c_bug_id, 'reporter_id', $t_old_data->reporter_id, $this->reporter_id);
     history_log_event_direct($c_bug_id, 'handler_id', $t_old_data->handler_id, $this->handler_id);
     history_log_event_direct($c_bug_id, 'priority', $t_old_data->priority, $this->priority);
     history_log_event_direct($c_bug_id, 'severity', $t_old_data->severity, $this->severity);
     history_log_event_direct($c_bug_id, 'reproducibility', $t_old_data->reproducibility, $this->reproducibility);
     history_log_event_direct($c_bug_id, 'status', $t_old_data->status, $this->status);
     history_log_event_direct($c_bug_id, 'resolution', $t_old_data->resolution, $this->resolution);
     history_log_event_direct($c_bug_id, 'projection', $t_old_data->projection, $this->projection);
     history_log_event_direct($c_bug_id, 'category', category_full_name($t_old_data->category_id, false), category_full_name($this->category_id, false));
     history_log_event_direct($c_bug_id, 'eta', $t_old_data->eta, $this->eta);
     history_log_event_direct($c_bug_id, 'os', $t_old_data->os, $this->os);
     history_log_event_direct($c_bug_id, 'os_build', $t_old_data->os_build, $this->os_build);
     history_log_event_direct($c_bug_id, 'platform', $t_old_data->platform, $this->platform);
     history_log_event_direct($c_bug_id, 'version', $t_old_data->version, $this->version);
     history_log_event_direct($c_bug_id, 'build', $t_old_data->build, $this->build);
     history_log_event_direct($c_bug_id, 'fixed_in_version', $t_old_data->fixed_in_version, $this->fixed_in_version);
     if ($t_roadmap_updated) {
         history_log_event_direct($c_bug_id, 'target_version', $t_old_data->target_version, $this->target_version);
     }
     history_log_event_direct($c_bug_id, 'view_state', $t_old_data->view_state, $this->view_state);
     history_log_event_direct($c_bug_id, 'summary', $t_old_data->summary, $this->summary);
     history_log_event_direct($c_bug_id, 'sponsorship_total', $t_old_data->sponsorship_total, $this->sponsorship_total);
     history_log_event_direct($c_bug_id, 'sticky', $t_old_data->sticky, $this->sticky);
     history_log_event_direct($c_bug_id, 'due_date', $t_old_data->due_date != date_get_null() ? $t_old_data->due_date : null, $this->due_date != date_get_null() ? $this->due_date : null);
     # Update extended info if requested
     if ($p_update_extended) {
         $t_bug_text_table = db_get_table('mantis_bug_text_table');
         $t_bug_text_id = bug_get_field($c_bug_id, 'bug_text_id');
         $query = "UPDATE {$t_bug_text_table}\n\t\t\t\t\t\t\tSET description=" . db_param() . ",\n\t\t\t\t\t\t\t\tsteps_to_reproduce=" . db_param() . ",\n\t\t\t\t\t\t\t\tadditional_information=" . db_param() . "\n\t\t\t\t\t\t\tWHERE id=" . db_param();
         db_query_bound($query, array($this->description, $this->steps_to_reproduce, $this->additional_information, $t_bug_text_id));
         bug_text_clear_cache($c_bug_id);
         $t_current_user = auth_get_current_user_id();
         if ($t_old_data->description != $this->description) {
             if (bug_revision_count($c_bug_id, REV_DESCRIPTION) < 1) {
                 $t_revision_id = bug_revision_add($c_bug_id, $t_old_data->reporter_id, REV_DESCRIPTION, $t_old_data->description, 0, $t_old_data->date_submitted);
             }
             $t_revision_id = bug_revision_add($c_bug_id, $t_current_user, REV_DESCRIPTION, $this->description);
             history_log_event_special($c_bug_id, DESCRIPTION_UPDATED, $t_revision_id);
         }
         if ($t_old_data->steps_to_reproduce != $this->steps_to_reproduce) {
             if (bug_revision_count($c_bug_id, REV_STEPS_TO_REPRODUCE) < 1) {
                 $t_revision_id = bug_revision_add($c_bug_id, $t_old_data->reporter_id, REV_STEPS_TO_REPRODUCE, $t_old_data->steps_to_reproduce, 0, $t_old_data->date_submitted);
             }
             $t_revision_id = bug_revision_add($c_bug_id, $t_current_user, REV_STEPS_TO_REPRODUCE, $this->steps_to_reproduce);
             history_log_event_special($c_bug_id, STEP_TO_REPRODUCE_UPDATED, $t_revision_id);
         }
         if ($t_old_data->additional_information != $this->additional_information) {
             if (bug_revision_count($c_bug_id, REV_ADDITIONAL_INFO) < 1) {
                 $t_revision_id = bug_revision_add($c_bug_id, $t_old_data->reporter_id, REV_ADDITIONAL_INFO, $t_old_data->additional_information, 0, $t_old_data->date_submitted);
             }
             $t_revision_id = bug_revision_add($c_bug_id, $t_current_user, REV_ADDITIONAL_INFO, $this->additional_information);
             history_log_event_special($c_bug_id, ADDITIONAL_INFO_UPDATED, $t_revision_id);
         }
     }
     # Update the last update date
     bug_update_date($c_bug_id);
     # allow bypass if user is sending mail separately
     if (false == $p_bypass_mail) {
         # bug assigned
         if ($t_old_data->handler_id != $this->handler_id) {
             email_generic($c_bug_id, 'owner', 'email_notification_title_for_action_bug_assigned');
             return true;
         }
         # status changed
         if ($t_old_data->status != $this->status) {
             $t_status = MantisEnum::getLabel(config_get('status_enum_string'), $this->status);
             $t_status = str_replace(' ', '_', $t_status);
             email_generic($c_bug_id, $t_status, 'email_notification_title_for_status_bug_' . $t_status);
             return true;
         }
         # @todo handle priority change if it requires special handling
         # generic update notification
         email_generic($c_bug_id, 'updated', 'email_notification_title_for_action_bug_updated');
     }
     return true;
 }
Example #19
0
/**
 * Print the legend for the status percentage
 * @return null
 */
function html_status_percentage_legend()
{
    $t_mantis_bug_table = db_get_table('mantis_bug_table');
    $t_project_id = helper_get_current_project();
    $t_user_id = auth_get_current_user_id();
    # checking if it's a per project statistic or all projects
    $t_specific_where = helper_project_specific_where($t_project_id, $t_user_id);
    $query = "SELECT status, COUNT(*) AS number\n\t\t\t\tFROM {$t_mantis_bug_table}\n\t\t\t\tWHERE {$t_specific_where}";
    if (!access_has_project_level(config_get('private_bug_threshold'))) {
        $query .= ' AND view_state < ' . VS_PRIVATE;
    }
    $query .= ' GROUP BY status';
    $result = db_query_bound($query);
    $t_bug_count = 0;
    $t_status_count_array = array();
    while ($row = db_fetch_array($result)) {
        $t_status_count_array[$row['status']] = $row['number'];
        $t_bug_count += $row['number'];
    }
    $t_enum_values = MantisEnum::getValues(config_get('status_enum_string'));
    $enum_count = count($t_enum_values);
    if ($t_bug_count > 0) {
        echo '<br />';
        echo '<table class="width100" cellspacing="1">';
        echo '<tr>';
        echo '<td class="form-title" colspan="' . $enum_count . '">' . lang_get('issue_status_percentage') . '</td>';
        echo '</tr>';
        echo '<tr>';
        foreach ($t_enum_values as $t_status) {
            $t_color = get_status_color($t_status);
            if (!isset($t_status_count_array[$t_status])) {
                $t_status_count_array[$t_status] = 0;
            }
            $width = round($t_status_count_array[$t_status] / $t_bug_count * 100);
            if ($width > 0) {
                echo "<td class=\"small-caption-center\" width=\"{$width}%\" bgcolor=\"{$t_color}\">{$width}%</td>";
            }
        }
        echo '</tr>';
        echo '</table>';
    }
}
Example #20
0
 * should only be known internally to the server.
 */
/**
 *	@todo Modify to run sections only on certain pages.
 *	eg. status colors are only necessary on a few pages.(my view, view all bugs, bug view, etc. )
 *	other pages may need to include dynamic css styles as well
 */
$t_referer_page = basename(parse_url($_SERVER['HTTP_REFERER'], PHP_URL_PATH));
switch ($t_referer_page) {
    case 'login_page.php':
    case 'signup_page.php':
    case 'lost_pwd_page.php':
    case 'account_update.php':
        # We don't need custom status colors on login page, and this is
        # actually causing an error since we're not authenticated yet.
        exit;
}
$t_status_string = config_get('status_enum_string');
$t_statuses = MantisEnum::getAssocArrayIndexedByValues($t_status_string);
$t_colors = config_get('status_colors');
$t_color_count = count($t_colors);
$t_color_width = $t_color_count > 0 ? round(100 / $t_color_count) : 0;
$t_status_percents = get_percentage_by_status();
foreach ($t_statuses as $t_id => $t_label) {
    if (array_key_exists($t_label, $t_colors)) {
        echo ".{$t_label}-color { background-color: {$t_colors[$t_label]}; width: {$t_color_width}%; }\n";
    }
    if (array_key_exists($t_id, $t_status_percents)) {
        echo ".{$t_label}-percentage { width: {$t_status_percents[$t_id]}%; }\n";
    }
}
Example #21
0
require_api('authentication_api.php');
require_api('compress_api.php');
require_api('config_api.php');
require_api('graphviz_api.php');
require_api('workflow_api.php');
auth_ensure_user_authenticated();
if (!config_get('relationship_graph_enable')) {
    access_denied();
}
compress_enable();
$t_status_arr = MantisEnum::getAssocArrayIndexedByValues(config_get('status_enum_string'));
$t_graph_fontname = config_get('relationship_graph_fontname');
$t_graph_fontsize = config_get('relationship_graph_fontsize');
$t_graph_fontpath = get_font_path();
$t_dot_tool = config_get('dot_tool');
$t_graph_attributes = array();
if (!empty($t_graph_fontpath)) {
    $t_graph_attributes['fontpath'] = $t_graph_fontpath;
}
$t_graph = new Graph('workflow', $t_graph_attributes, $t_dot_tool);
$t_graph->set_default_node_attr(array('fontname' => $t_graph_fontname, 'fontsize' => $t_graph_fontsize, 'shape' => 'record', 'style' => 'filled', 'height' => '0.2', 'width' => '0.4'));
$t_graph->set_default_edge_attr(array('style' => 'solid', 'color' => '#0000C0', 'dir' => 'forward'));
foreach ($t_status_arr as $t_from_status => $t_from_label) {
    $t_enum_status = MantisEnum::getAssocArrayIndexedByValues(config_get('status_enum_string'));
    foreach ($t_enum_status as $t_to_status_id => $t_to_status_label) {
        if (workflow_transition_edge_exists($t_from_status, $t_to_status_id)) {
            $t_graph->add_edge(string_no_break(MantisEnum::getLabel(lang_get('status_enum_string'), $t_from_status)), string_no_break(MantisEnum::getLabel(lang_get('status_enum_string'), $t_to_status_id)), array());
        }
    }
}
$t_graph->output('png', true);
Example #22
0
/**
 * get the css class name for the given status, user and project
 * @param int $p_status
 * @return string
 */
function html_get_status_css_class($p_status, $p_user = null, $p_project = null)
{
    return string_attribute(MantisEnum::getLabel(config_get('status_enum_string', null, $p_user, $p_project), $p_status) . '-color');
}
/**
 * HTML for Row
 *
 * @param string $p_caption      Caption.
 * @param string $p_message_type Message type.
 * @return void
 */
function get_capability_row_for_email($p_caption, $p_message_type)
{
    $t_access_levels = MantisEnum::getValues(config_get('access_levels_enum_string'));
    echo '<tr><td>' . string_display($p_caption) . '</td>' . "\n";
    echo '  <td' . color_notify_flag($p_message_type, 'reporter') . '>' . show_notify_flag($p_message_type, 'reporter') . '</td>' . "\n";
    echo '  <td' . color_notify_flag($p_message_type, 'handler') . '>' . show_notify_flag($p_message_type, 'handler') . '</td>' . "\n";
    echo '  <td' . color_notify_flag($p_message_type, 'monitor') . '>' . show_notify_flag($p_message_type, 'monitor') . '</td>' . "\n";
    echo '  <td' . color_notify_flag($p_message_type, 'bugnotes') . '>' . show_notify_flag($p_message_type, 'bugnotes') . '</td>' . "\n";
    echo '  <td' . color_notify_flag($p_message_type, 'category') . '>' . show_notify_flag($p_message_type, 'category') . '</td>' . "\n";
    foreach ($t_access_levels as $t_access_level) {
        echo '  <td' . color_threshold_flag($t_access_level, $p_message_type) . '>' . show_notify_threshold($t_access_level, $p_message_type) . '</td>' . "\n";
    }
    echo '</tr>' . "\n";
}
Example #24
0
 /**
  * Checks if the specified enum string contains the specified value.
  *
  * @param string $enumString  The enumeration string.
  * @param integer $value      The value to chec,
  * @return bool true if found, false otherwise.
  */
 public static function hasValue($enumString, $value)
 {
     $assocArray = MantisEnum::getAssocArrayIndexedByValues($enumString);
     $valueAsInteger = (int) $value;
     return isset($assocArray[$valueAsInteger]);
 }
function get_capability_enum($p_caption, $p_threshold, $p_enum, $p_all_projects_only = false)
{
    global $t_user, $t_project_id, $t_show_submit, $t_access_levels, $t_colour_project, $t_colour_global;
    $t_file = config_get_global($p_threshold);
    $t_global = config_get($p_threshold, null, null, ALL_PROJECTS);
    $t_project = config_get($p_threshold);
    $t_can_change = access_has_project_level(config_get_access($p_threshold), $t_project_id, $t_user) && (ALL_PROJECTS == $t_project_id || !$p_all_projects_only);
    $t_colour = '';
    if ($t_global != $t_file) {
        $t_colour = ' bgcolor="' . $t_colour_global . '" ';
        # all projects override
        if ($t_can_change) {
            set_overrides($p_threshold);
        }
    }
    if ($t_project != $t_global) {
        $t_colour = ' bgcolor="' . $t_colour_project . '" ';
        # project overrides
        if ($t_can_change) {
            set_overrides($p_threshold);
        }
    }
    echo '<tr ' . helper_alternate_class() . '><td>' . string_display($p_caption) . '</td>';
    if ($t_can_change) {
        echo '<td class="left" colspan="3"' . $t_colour . '><select name="flag_' . $p_threshold . '">';
        print_enum_string_option_list($p_enum, config_get($p_threshold));
        echo '</select></td><td colspan="' . (count($t_access_levels) - 3) . '"></td>';
        $t_show_submit = true;
    } else {
        $t_value = MantisEnum::getLabel(lang_get($p_enum . '_enum_string'), config_get($p_threshold)) . '&nbsp;';
        echo '<td class="left" colspan="3"' . $t_colour . '>' . $t_value . '</td><td colspan="' . (count($t_access_levels) - 3) . '"></td>';
    }
    if ($t_can_change) {
        echo '<td><select name="access_' . $p_threshold . '">';
        print_enum_string_option_list('access_levels', config_get_access($p_threshold));
        echo '</select> </td>';
    } else {
        echo '<td>' . MantisEnum::getLabel(lang_get('access_levels_enum_string'), config_get_access($p_threshold)) . '&nbsp;</td>';
    }
    echo '</tr>' . "\n";
}
/**
 * Get enumeration row
 * @param string  $p_caption           Caption.
 * @param string  $p_threshold         Threshold.
 * @param string  $p_enum              Enumeration.
 * @param boolean $p_all_projects_only All projects only.
 * @return void
 */
function get_capability_enum($p_caption, $p_threshold, $p_enum, $p_all_projects_only = false)
{
    global $g_user, $g_project_id, $t_show_submit, $g_access_levels;
    $t_file = config_get_global($p_threshold);
    $t_global = config_get($p_threshold, null, null, ALL_PROJECTS);
    $t_project = config_get($p_threshold);
    $t_can_change = access_has_project_level(config_get_access($p_threshold), $g_project_id, $g_user) && (ALL_PROJECTS == $g_project_id || !$p_all_projects_only);
    echo '<tr>' . "\n";
    echo "\t" . '<td>' . string_display($p_caption) . '</td>' . "\n";
    # Value
    $t_color = set_color($p_threshold, $t_file, $t_global, $t_project, $t_can_change);
    echo "\t" . '<td class="left" colspan="3"' . $t_color . '>';
    if ($t_can_change) {
        echo '<select name="flag_' . $p_threshold . '">';
        print_enum_string_option_list($p_enum, config_get($p_threshold));
        echo '</select>';
        $t_show_submit = true;
    } else {
        $t_value = MantisEnum::getLabel(lang_get($p_enum . '_enum_string'), config_get($p_threshold)) . '&#160;';
        echo $t_value;
    }
    echo '</td>' . "\n\t" . '<td colspan="' . (count($g_access_levels) - 3) . '"></td>' . "\n";
    print_who_can_change($p_threshold, $t_can_change);
    echo '</tr>' . "\n";
}
Example #27
0
/**
 * Get set of bug rows from given filter
 * @todo Had to make all these parameters required because we can't use call-time pass by reference anymore.
 * I really preferred not having to pass all the params in if you didn't want to, but I wanted to get
 * rid of the errors for now.  If we can think of a better way later (maybe return an object) that would be great.
 *
 * @param integer &$p_page_number  Page number of the page you want to see (set to the actual page on return).
 * @param integer &$p_per_page     The number of bugs to see per page (set to actual on return)
 *                                 -1   indicates you want to see all bugs
 *                                 null indicates you want to use the value specified in the filter.
 * @param integer &$p_page_count   You don't need to give a value here, the number of pages will be stored here on return.
 * @param integer &$p_bug_count    You don't need to give a value here, the number of bugs will be stored here on return.
 * @param mixed   $p_custom_filter Custom Filter to use.
 * @param integer $p_project_id    Project id to use in filtering.
 * @param integer $p_user_id       User id to use as current user when filtering.
 * @param boolean $p_show_sticky   True/false - get sticky issues only.
 * @return boolean|array
 */
function filter_get_bug_rows(&$p_page_number, &$p_per_page, &$p_page_count, &$p_bug_count, $p_custom_filter = null, $p_project_id = null, $p_user_id = null, $p_show_sticky = null)
{
    log_event(LOG_FILTERING, 'START NEW FILTER QUERY');
    $t_limit_reporters = config_get('limit_reporters');
    $t_report_bug_threshold = config_get('report_bug_threshold');
    $t_where_param_count = 0;
    $t_current_user_id = auth_get_current_user_id();
    if ($p_user_id === null || $p_user_id === 0) {
        $t_user_id = $t_current_user_id;
    } else {
        $t_user_id = $p_user_id;
    }
    $c_user_id = (int) $t_user_id;
    if (null === $p_project_id) {
        # @@@ If project_id is not specified, then use the project id(s) in the filter if set, otherwise, use current project.
        $t_project_id = helper_get_current_project();
    } else {
        $t_project_id = $p_project_id;
    }
    if ($p_custom_filter === null) {
        # Prefer current_user_get_bug_filter() over user_get_filter() when applicable since it supports
        # cookies set by previous version of the code.
        if ($t_user_id == $t_current_user_id) {
            $t_filter = current_user_get_bug_filter();
        } else {
            $t_filter = user_get_bug_filter($t_user_id, $t_project_id);
        }
    } else {
        $t_filter = $p_custom_filter;
    }
    # if filter isn't return above, create a new filter from an empty array.
    if (false === $t_filter) {
        $t_filter = array();
    }
    $t_filter = filter_ensure_valid_filter($t_filter);
    $t_view_type = $t_filter['_view_type'];
    # project query clauses must be AND-ed always, irrespective of how the filter
    # clauses are requested by the user ( all matching -> AND, any matching -> OR )
    $t_where_clauses = array();
    $t_project_where_clauses = array('{project}.enabled = ' . db_param());
    $t_where_params = array(1);
    $t_select_clauses = array('{bug}.*');
    $t_from_clauses = array('{bug}');
    $t_join_clauses = array(' JOIN {project} ON {project}.id = {bug}.project_id');
    # normalize the project filtering into an array $t_project_ids
    if ('simple' == $t_view_type) {
        log_event(LOG_FILTERING, 'Simple Filter');
        $t_project_ids = array($t_project_id);
        $t_include_sub_projects = true;
    } else {
        log_event(LOG_FILTERING, 'Advanced Filter');
        if (!is_array($t_filter[FILTER_PROPERTY_PROJECT_ID])) {
            $t_project_ids = array((int) $t_filter[FILTER_PROPERTY_PROJECT_ID]);
        } else {
            $t_project_ids = array_map('intval', $t_filter[FILTER_PROPERTY_PROJECT_ID]);
        }
        $t_include_sub_projects = count($t_project_ids) == 1 && ($t_project_ids[0] == META_FILTER_CURRENT || $t_project_ids[0] == ALL_PROJECTS);
    }
    log_event(LOG_FILTERING, 'project_ids = @P' . implode(', @P', $t_project_ids));
    log_event(LOG_FILTERING, 'include sub-projects = ' . ($t_include_sub_projects ? '1' : '0'));
    # if the array has ALL_PROJECTS, then reset the array to only contain ALL_PROJECTS.
    # replace META_FILTER_CURRENT with the actualy current project id.
    $t_all_projects_found = false;
    $t_new_project_ids = array();
    foreach ($t_project_ids as $t_pid) {
        if ($t_pid == META_FILTER_CURRENT) {
            $t_pid = $t_project_id;
        }
        if ($t_pid == ALL_PROJECTS) {
            $t_all_projects_found = true;
            log_event(LOG_FILTERING, 'all projects selected');
            break;
        }
        # filter out inaccessible projects.
        if (!project_exists($t_pid) || !access_has_project_level(config_get('view_bug_threshold', null, $t_user_id, $t_pid), $t_pid, $t_user_id)) {
            log_event(LOG_FILTERING, 'Invalid or inaccessible project: ' . $t_pid);
            continue;
        }
        $t_new_project_ids[] = $t_pid;
    }
    $t_projects_query_required = true;
    if ($t_all_projects_found) {
        if (user_is_administrator($t_user_id)) {
            log_event(LOG_FILTERING, 'all projects + administrator, hence no project filter.');
            $t_projects_query_required = false;
        } else {
            $t_project_ids = user_get_accessible_projects($t_user_id);
        }
    } else {
        $t_project_ids = $t_new_project_ids;
    }
    if ($t_projects_query_required) {
        # expand project ids to include sub-projects
        if ($t_include_sub_projects) {
            $t_top_project_ids = $t_project_ids;
            foreach ($t_top_project_ids as $t_pid) {
                log_event(LOG_FILTERING, 'Getting sub-projects for project id @P' . $t_pid);
                $t_subproject_ids = user_get_all_accessible_subprojects($t_user_id, $t_pid);
                if (!$t_subproject_ids) {
                    continue;
                }
                $t_project_ids = array_merge($t_project_ids, $t_subproject_ids);
            }
            $t_project_ids = array_unique($t_project_ids);
        }
        # if no projects are accessible, then return an empty array.
        if (count($t_project_ids) == 0) {
            log_event(LOG_FILTERING, 'no accessible projects');
            return array();
        }
        log_event(LOG_FILTERING, 'project_ids after including sub-projects = @P' . implode(', @P', $t_project_ids));
        # this array is to be populated with project ids for which we only want to show public issues.  This is due to the limited
        # access of the current user.
        $t_public_only_project_ids = array();
        # this array is populated with project ids that the current user has full access to.
        $t_private_and_public_project_ids = array();
        $t_limited_projects = array();
        foreach ($t_project_ids as $t_pid) {
            # limit reporters to visible projects
            if (ON === $t_limit_reporters && !access_has_project_level(config_get('report_bug_threshold', null, $t_user_id, $t_pid) + 1, $t_pid, $t_user_id)) {
                array_push($t_limited_projects, '({bug}.project_id=' . $t_pid . ' AND ({bug}.reporter_id=' . $t_user_id . ') )');
            } else {
                $t_access_required_to_view_private_bugs = config_get('private_bug_threshold', null, null, $t_pid);
                if (access_has_project_level($t_access_required_to_view_private_bugs, $t_pid, $t_user_id)) {
                    $t_private_and_public_project_ids[] = $t_pid;
                } else {
                    $t_public_only_project_ids[] = $t_pid;
                }
            }
        }
        log_event(LOG_FILTERING, 'project_ids (with public/private access) = @P' . implode(', @P', $t_private_and_public_project_ids));
        log_event(LOG_FILTERING, 'project_ids (with public access) = @P' . implode(', @P', $t_public_only_project_ids));
        $t_count_private_and_public_project_ids = count($t_private_and_public_project_ids);
        if ($t_count_private_and_public_project_ids == 1) {
            $t_private_and_public_query = '( {bug}.project_id = ' . $t_private_and_public_project_ids[0] . ' )';
        } else {
            if ($t_count_private_and_public_project_ids > 1) {
                $t_private_and_public_query = '( {bug}.project_id in (' . implode(', ', $t_private_and_public_project_ids) . ') )';
            } else {
                $t_private_and_public_query = null;
            }
        }
        $t_count_public_only_project_ids = count($t_public_only_project_ids);
        $t_public_view_state_check = '( ( {bug}.view_state = ' . VS_PUBLIC . ' ) OR ( {bug}.reporter_id = ' . $t_user_id . ') )';
        if ($t_count_public_only_project_ids == 1) {
            $t_public_only_query = '( ( {bug}.project_id = ' . $t_public_only_project_ids[0] . ' ) AND ' . $t_public_view_state_check . ')';
        } else {
            if ($t_count_public_only_project_ids > 1) {
                $t_public_only_query = '( ( {bug}.project_id in (' . implode(', ', $t_public_only_project_ids) . ') ) AND ' . $t_public_view_state_check . ')';
            } else {
                $t_public_only_query = null;
            }
        }
        # both queries can't be null, so we either have one of them or both.
        if ($t_private_and_public_query === null) {
            $t_project_query = $t_public_only_query;
        } else {
            if ($t_public_only_query === null) {
                $t_project_query = $t_private_and_public_query;
            } else {
                $t_project_query = '( ' . $t_public_only_query . ' OR ' . $t_private_and_public_query . ' )';
            }
        }
        if (!empty($t_limited_projects)) {
            foreach ($t_limited_projects as $t_string) {
                if ($t_project_query == "") {
                    $t_project_query = " ( {$t_string} ) ";
                } else {
                    $t_project_query = " ( {$t_project_query} OR ( {$t_string} ) )";
                }
            }
        }
        log_event(LOG_FILTERING, 'project query = ' . $t_project_query);
        array_push($t_project_where_clauses, $t_project_query);
    }
    # date filter
    if ('on' == $t_filter[FILTER_PROPERTY_FILTER_BY_DATE] && is_numeric($t_filter[FILTER_PROPERTY_START_MONTH]) && is_numeric($t_filter[FILTER_PROPERTY_START_DAY]) && is_numeric($t_filter[FILTER_PROPERTY_START_YEAR]) && is_numeric($t_filter[FILTER_PROPERTY_END_MONTH]) && is_numeric($t_filter[FILTER_PROPERTY_END_DAY]) && is_numeric($t_filter[FILTER_PROPERTY_END_YEAR])) {
        $t_start_string = $t_filter[FILTER_PROPERTY_START_YEAR] . '-' . $t_filter[FILTER_PROPERTY_START_MONTH] . '-' . $t_filter[FILTER_PROPERTY_START_DAY] . ' 00:00:00';
        $t_end_string = $t_filter[FILTER_PROPERTY_END_YEAR] . '-' . $t_filter[FILTER_PROPERTY_END_MONTH] . '-' . $t_filter[FILTER_PROPERTY_END_DAY] . ' 23:59:59';
        $t_where_params[] = strtotime($t_start_string);
        $t_where_params[] = strtotime($t_end_string);
        array_push($t_project_where_clauses, '({bug}.date_submitted BETWEEN ' . db_param() . ' AND ' . db_param() . ' )');
    }
    # view state
    $t_view_state = (int) $t_filter[FILTER_PROPERTY_VIEW_STATE];
    if (!filter_field_is_any($t_filter[FILTER_PROPERTY_VIEW_STATE])) {
        $t_view_state_query = '({bug}.view_state=' . db_param() . ')';
        log_event(LOG_FILTERING, 'view_state query = ' . $t_view_state_query);
        $t_where_params[] = $t_view_state;
        array_push($t_where_clauses, $t_view_state_query);
    } else {
        log_event(LOG_FILTERING, 'no view_state query');
    }
    # reporter
    if (!filter_field_is_any($t_filter[FILTER_PROPERTY_REPORTER_ID])) {
        $t_clauses = array();
        foreach ($t_filter[FILTER_PROPERTY_REPORTER_ID] as $t_filter_member) {
            if (filter_field_is_none($t_filter_member)) {
                array_push($t_clauses, '0');
            } else {
                $c_reporter_id = (int) $t_filter_member;
                if (filter_field_is_myself($c_reporter_id)) {
                    array_push($t_clauses, $c_user_id);
                } else {
                    array_push($t_clauses, $c_reporter_id);
                }
            }
        }
        if (1 < count($t_clauses)) {
            $t_reporter_query = '( {bug}.reporter_id in (' . implode(', ', $t_clauses) . ') )';
        } else {
            $t_reporter_query = '( {bug}.reporter_id=' . $t_clauses[0] . ' )';
        }
        log_event(LOG_FILTERING, 'reporter query = ' . $t_reporter_query);
        array_push($t_where_clauses, $t_reporter_query);
    } else {
        log_event(LOG_FILTERING, 'no reporter query');
    }
    # handler
    if (!filter_field_is_any($t_filter[FILTER_PROPERTY_HANDLER_ID])) {
        $t_clauses = array();
        foreach ($t_filter[FILTER_PROPERTY_HANDLER_ID] as $t_filter_member) {
            if (filter_field_is_none($t_filter_member)) {
                array_push($t_clauses, 0);
            } else {
                $c_handler_id = (int) $t_filter_member;
                if (filter_field_is_myself($c_handler_id)) {
                    array_push($t_clauses, $c_user_id);
                } else {
                    array_push($t_clauses, $c_handler_id);
                }
            }
        }
        if (1 < count($t_clauses)) {
            $t_handler_query = '( {bug}.handler_id in (' . implode(', ', $t_clauses) . ') )';
        } else {
            $t_handler_query = '( {bug}.handler_id=' . $t_clauses[0] . ' )';
        }
        log_event(LOG_FILTERING, 'handler query = ' . $t_handler_query);
        array_push($t_where_clauses, $t_handler_query);
    } else {
        log_event(LOG_FILTERING, 'no handler query');
    }
    # category
    if (!filter_field_is_any($t_filter[FILTER_PROPERTY_CATEGORY_ID])) {
        $t_clauses = array();
        foreach ($t_filter[FILTER_PROPERTY_CATEGORY_ID] as $t_filter_member) {
            if (!filter_field_is_none($t_filter_member)) {
                array_push($t_clauses, $t_filter_member);
            }
        }
        if (1 < count($t_clauses)) {
            $t_where_tmp = array();
            foreach ($t_clauses as $t_clause) {
                $t_where_tmp[] = db_param();
                $t_where_params[] = $t_clause;
            }
            array_push($t_where_clauses, '( {bug}.category_id in ( SELECT id FROM {category} WHERE name in (' . implode(', ', $t_where_tmp) . ') ) )');
        } else {
            $t_where_params[] = $t_clauses[0];
            array_push($t_where_clauses, '( {bug}.category_id in ( SELECT id FROM {category} WHERE name=' . db_param() . ') )');
        }
    }
    # severity
    if (!filter_field_is_any($t_filter[FILTER_PROPERTY_SEVERITY])) {
        $t_clauses = array();
        foreach ($t_filter[FILTER_PROPERTY_SEVERITY] as $t_filter_member) {
            $c_show_severity = (int) $t_filter_member;
            array_push($t_clauses, $c_show_severity);
        }
        if (1 < count($t_clauses)) {
            $t_where_tmp = array();
            foreach ($t_clauses as $t_clause) {
                $t_where_tmp[] = db_param();
                $t_where_params[] = $t_clause;
            }
            array_push($t_where_clauses, '( {bug}.severity in (' . implode(', ', $t_where_tmp) . ') )');
        } else {
            $t_where_params[] = $t_clauses[0];
            array_push($t_where_clauses, '( {bug}.severity=' . db_param() . ' )');
        }
    }
    # show / hide status
    # take a list of all available statuses then remove the ones that we want hidden, then make sure
    # the ones we want shown are still available
    $t_desired_statuses = array();
    $t_available_statuses = MantisEnum::getValues(config_get('status_enum_string'));
    if ('simple' == $t_filter['_view_type']) {
        # simple filtering: if showing any, restrict by the hide status value, otherwise ignore the hide
        $t_this_status = $t_filter[FILTER_PROPERTY_STATUS][0];
        $t_this_hide_status = isset($t_filter[FILTER_PROPERTY_HIDE_STATUS][0]) ? $t_filter[FILTER_PROPERTY_HIDE_STATUS][0] : null;
        if (filter_field_is_any($t_this_status)) {
            foreach ($t_available_statuses as $t_this_available_status) {
                if ($t_this_hide_status > $t_this_available_status) {
                    $t_desired_statuses[] = $t_this_available_status;
                }
            }
        } else {
            $t_desired_statuses[] = $t_this_status;
        }
    } else {
        # advanced filtering: ignore the hide
        if (filter_field_is_any($t_filter[FILTER_PROPERTY_STATUS])) {
            $t_desired_statuses = array();
        } else {
            foreach ($t_filter[FILTER_PROPERTY_STATUS] as $t_this_status) {
                $t_desired_statuses[] = $t_this_status;
            }
        }
    }
    if (count($t_desired_statuses) > 0) {
        $t_clauses = array();
        foreach ($t_desired_statuses as $t_filter_member) {
            $c_show_status = (int) $t_filter_member;
            array_push($t_clauses, $c_show_status);
        }
        if (1 < count($t_clauses)) {
            $t_where_tmp = array();
            foreach ($t_clauses as $t_clause) {
                $t_where_tmp[] = db_param();
                $t_where_params[] = $t_clause;
            }
            array_push($t_where_clauses, '( {bug}.status in (' . implode(', ', $t_where_tmp) . ') )');
        } else {
            $t_where_params[] = $t_clauses[0];
            array_push($t_where_clauses, '( {bug}.status=' . db_param() . ' )');
        }
    }
    # resolution
    if (!filter_field_is_any($t_filter[FILTER_PROPERTY_RESOLUTION])) {
        $t_clauses = array();
        foreach ($t_filter[FILTER_PROPERTY_RESOLUTION] as $t_filter_member) {
            $c_show_resolution = (int) $t_filter_member;
            array_push($t_clauses, $c_show_resolution);
        }
        if (1 < count($t_clauses)) {
            $t_where_tmp = array();
            foreach ($t_clauses as $t_clause) {
                $t_where_tmp[] = db_param();
                $t_where_params[] = $t_clause;
            }
            array_push($t_where_clauses, '( {bug}.resolution in (' . implode(', ', $t_where_tmp) . ') )');
        } else {
            $t_where_params[] = $t_clauses[0];
            array_push($t_where_clauses, '( {bug}.resolution=' . db_param() . ' )');
        }
    }
    # priority
    if (!filter_field_is_any($t_filter[FILTER_PROPERTY_PRIORITY])) {
        $t_clauses = array();
        foreach ($t_filter[FILTER_PROPERTY_PRIORITY] as $t_filter_member) {
            $c_show_priority = (int) $t_filter_member;
            array_push($t_clauses, $c_show_priority);
        }
        if (1 < count($t_clauses)) {
            $t_where_tmp = array();
            foreach ($t_clauses as $t_clause) {
                $t_where_tmp[] = db_param();
                $t_where_params[] = $t_clause;
            }
            array_push($t_where_clauses, '( {bug}.priority in (' . implode(', ', $t_where_tmp) . ') )');
        } else {
            $t_where_params[] = $t_clauses[0];
            array_push($t_where_clauses, '( {bug}.priority=' . db_param() . ' )');
        }
    }
    # product build
    if (!filter_field_is_any($t_filter[FILTER_PROPERTY_BUILD])) {
        $t_clauses = array();
        foreach ($t_filter[FILTER_PROPERTY_BUILD] as $t_filter_member) {
            $t_filter_member = stripslashes($t_filter_member);
            if (filter_field_is_none($t_filter_member)) {
                array_push($t_clauses, '');
            } else {
                $c_show_build = $t_filter_member;
                array_push($t_clauses, $c_show_build);
            }
        }
        if (1 < count($t_clauses)) {
            $t_where_tmp = array();
            foreach ($t_clauses as $t_clause) {
                $t_where_tmp[] = db_param();
                $t_where_params[] = $t_clause;
            }
            array_push($t_where_clauses, '( {bug}.build in (' . implode(', ', $t_where_tmp) . ') )');
        } else {
            $t_where_params[] = $t_clauses[0];
            array_push($t_where_clauses, '( {bug}.build=' . db_param() . ' )');
        }
    }
    # product version
    if (!filter_field_is_any($t_filter[FILTER_PROPERTY_VERSION])) {
        $t_clauses = array();
        foreach ($t_filter[FILTER_PROPERTY_VERSION] as $t_filter_member) {
            $t_filter_member = stripslashes($t_filter_member);
            if (filter_field_is_none($t_filter_member)) {
                array_push($t_clauses, '');
            } else {
                $c_show_version = $t_filter_member;
                array_push($t_clauses, $c_show_version);
            }
        }
        if (1 < count($t_clauses)) {
            $t_where_tmp = array();
            foreach ($t_clauses as $t_clause) {
                $t_where_tmp[] = db_param();
                $t_where_params[] = $t_clause;
            }
            array_push($t_where_clauses, '( {bug}.version in (' . implode(', ', $t_where_tmp) . ') )');
        } else {
            $t_where_params[] = $t_clauses[0];
            array_push($t_where_clauses, '( {bug}.version=' . db_param() . ' )');
        }
    }
    # profile
    if (!filter_field_is_any($t_filter[FILTER_PROPERTY_PROFILE_ID])) {
        $t_clauses = array();
        foreach ($t_filter[FILTER_PROPERTY_PROFILE_ID] as $t_filter_member) {
            $t_filter_member = stripslashes($t_filter_member);
            if (filter_field_is_none($t_filter_member)) {
                array_push($t_clauses, '0');
            } else {
                $c_show_profile = (int) $t_filter_member;
                array_push($t_clauses, $c_show_profile);
            }
        }
        if (1 < count($t_clauses)) {
            $t_where_tmp = array();
            foreach ($t_clauses as $t_clause) {
                $t_where_tmp[] = db_param();
                $t_where_params[] = $t_clause;
            }
            array_push($t_where_clauses, '( {bug}.profile_id in (' . implode(', ', $t_where_tmp) . ') )');
        } else {
            $t_where_params[] = $t_clauses[0];
            array_push($t_where_clauses, '( {bug}.profile_id=' . db_param() . ' )');
        }
    }
    # platform
    if (!filter_field_is_any($t_filter[FILTER_PROPERTY_PLATFORM])) {
        $t_clauses = array();
        foreach ($t_filter[FILTER_PROPERTY_PLATFORM] as $t_filter_member) {
            $t_filter_member = stripslashes($t_filter_member);
            if (filter_field_is_none($t_filter_member)) {
                array_push($t_clauses, '');
            } else {
                $c_platform = $t_filter_member;
                array_push($t_clauses, $c_platform);
            }
        }
        if (1 < count($t_clauses)) {
            $t_where_tmp = array();
            foreach ($t_clauses as $t_clause) {
                $t_where_tmp[] = db_param();
                $t_where_params[] = $t_clause;
            }
            array_push($t_where_clauses, '( {bug}.platform in (' . implode(', ', $t_where_tmp) . ') )');
        } else {
            $t_where_params[] = $t_clauses[0];
            array_push($t_where_clauses, '( {bug}.platform = ' . db_param() . ' )');
        }
    }
    # Operating System (os)
    if (!filter_field_is_any($t_filter[FILTER_PROPERTY_OS])) {
        $t_clauses = array();
        foreach ($t_filter[FILTER_PROPERTY_OS] as $t_filter_member) {
            $t_filter_member = stripslashes($t_filter_member);
            if (filter_field_is_none($t_filter_member)) {
                array_push($t_clauses, '');
            } else {
                $c_os = $t_filter_member;
                array_push($t_clauses, $c_os);
            }
        }
        if (1 < count($t_clauses)) {
            $t_where_tmp = array();
            foreach ($t_clauses as $t_clause) {
                $t_where_tmp[] = db_param();
                $t_where_params[] = $t_clause;
            }
            array_push($t_where_clauses, '( {bug}.os in (' . implode(', ', $t_where_tmp) . ') )');
        } else {
            $t_where_params[] = $t_clauses[0];
            array_push($t_where_clauses, '( {bug}.os = ' . db_param() . ' )');
        }
    }
    # Operating System Build (os_build)
    if (!filter_field_is_any($t_filter[FILTER_PROPERTY_OS_BUILD])) {
        $t_clauses = array();
        foreach ($t_filter[FILTER_PROPERTY_OS_BUILD] as $t_filter_member) {
            $t_filter_member = stripslashes($t_filter_member);
            if (filter_field_is_none($t_filter_member)) {
                array_push($t_clauses, '');
            } else {
                $c_os_build = $t_filter_member;
                array_push($t_clauses, $c_os_build);
            }
        }
        if (1 < count($t_clauses)) {
            $t_where_tmp = array();
            foreach ($t_clauses as $t_clause) {
                $t_where_tmp[] = db_param();
                $t_where_params[] = $t_clause;
            }
            array_push($t_where_clauses, '( {bug}.os_build in (' . implode(', ', $t_where_tmp) . ') )');
        } else {
            $t_where_params[] = $t_clauses[0];
            array_push($t_where_clauses, '( {bug}.os_build = ' . db_param() . ' )');
        }
    }
    # fixed in version
    if (!filter_field_is_any($t_filter[FILTER_PROPERTY_FIXED_IN_VERSION])) {
        $t_clauses = array();
        foreach ($t_filter[FILTER_PROPERTY_FIXED_IN_VERSION] as $t_filter_member) {
            $t_filter_member = stripslashes($t_filter_member);
            if (filter_field_is_none($t_filter_member)) {
                array_push($t_clauses, '');
            } else {
                $c_fixed_in_version = $t_filter_member;
                array_push($t_clauses, $c_fixed_in_version);
            }
        }
        if (1 < count($t_clauses)) {
            $t_where_tmp = array();
            foreach ($t_clauses as $t_clause) {
                $t_where_tmp[] = db_param();
                $t_where_params[] = $t_clause;
            }
            array_push($t_where_clauses, '( {bug}.fixed_in_version in (' . implode(', ', $t_where_tmp) . ') )');
        } else {
            $t_where_params[] = $t_clauses[0];
            array_push($t_where_clauses, '( {bug}.fixed_in_version=' . db_param() . ' )');
        }
    }
    # target version
    if (!filter_field_is_any($t_filter[FILTER_PROPERTY_TARGET_VERSION])) {
        $t_clauses = array();
        foreach ($t_filter[FILTER_PROPERTY_TARGET_VERSION] as $t_filter_member) {
            $t_filter_member = stripslashes($t_filter_member);
            if (filter_field_is_none($t_filter_member)) {
                array_push($t_clauses, '');
            } else {
                $c_target_version = $t_filter_member;
                array_push($t_clauses, $c_target_version);
            }
        }
        # echo var_dump( $t_clauses ); exit;
        if (1 < count($t_clauses)) {
            $t_where_tmp = array();
            foreach ($t_clauses as $t_clause) {
                $t_where_tmp[] = db_param();
                $t_where_params[] = $t_clause;
            }
            array_push($t_where_clauses, '( {bug}.target_version in (' . implode(', ', $t_where_tmp) . ') )');
        } else {
            $t_where_params[] = $t_clauses[0];
            array_push($t_where_clauses, '( {bug}.target_version=' . db_param() . ' )');
        }
    }
    # users monitoring a bug
    if (!filter_field_is_any($t_filter[FILTER_PROPERTY_MONITOR_USER_ID])) {
        $t_clauses = array();
        $t_table_name = 'user_monitor';
        array_push($t_join_clauses, 'LEFT JOIN {bug_monitor} ' . $t_table_name . ' ON ' . $t_table_name . '.bug_id = {bug}.id');
        foreach ($t_filter[FILTER_PROPERTY_MONITOR_USER_ID] as $t_filter_member) {
            $c_user_monitor = (int) $t_filter_member;
            if (filter_field_is_myself($c_user_monitor)) {
                array_push($t_clauses, $c_user_id);
            } else {
                array_push($t_clauses, $c_user_monitor);
            }
        }
        if (1 < count($t_clauses)) {
            $t_where_tmp = array();
            foreach ($t_clauses as $t_clause) {
                $t_where_tmp[] = db_param();
                $t_where_params[] = $t_clause;
            }
            array_push($t_where_clauses, '( ' . $t_table_name . '.user_id in (' . implode(', ', $t_where_tmp) . ') )');
        } else {
            $t_where_params[] = $t_clauses[0];
            array_push($t_where_clauses, '( ' . $t_table_name . '.user_id=' . db_param() . ' )');
        }
    }
    # bug relationship
    $t_any_found = false;
    $c_rel_type = $t_filter[FILTER_PROPERTY_RELATIONSHIP_TYPE];
    $c_rel_bug = $t_filter[FILTER_PROPERTY_RELATIONSHIP_BUG];
    if (-1 == $c_rel_type || 0 == $c_rel_bug) {
        $t_any_found = true;
    }
    if (!$t_any_found) {
        # use the complementary type
        $t_comp_type = relationship_get_complementary_type($c_rel_type);
        $t_clauses = array();
        $t_table_dst = 'rel_dst';
        $t_table_src = 'rel_src';
        array_push($t_join_clauses, 'LEFT JOIN {bug_relationship} ' . $t_table_dst . ' ON ' . $t_table_dst . '.destination_bug_id = {bug}.id');
        array_push($t_join_clauses, 'LEFT JOIN {bug_relationship} ' . $t_table_src . ' ON ' . $t_table_src . '.source_bug_id = {bug}.id');
        # get reverse relationships
        $t_where_params[] = $t_comp_type;
        $t_where_params[] = $c_rel_bug;
        $t_where_params[] = $c_rel_type;
        $t_where_params[] = $c_rel_bug;
        array_push($t_clauses, '(' . $t_table_dst . '.relationship_type=' . db_param() . ' AND ' . $t_table_dst . '.source_bug_id=' . db_param() . ')');
        array_push($t_clauses, '(' . $t_table_src . '.relationship_type=' . db_param() . ' AND ' . $t_table_src . '.destination_bug_id=' . db_param() . ')');
        array_push($t_where_clauses, '(' . implode(' OR ', $t_clauses) . ')');
    }
    # tags
    $c_tag_string = trim($t_filter[FILTER_PROPERTY_TAG_STRING]);
    $c_tag_select = trim($t_filter[FILTER_PROPERTY_TAG_SELECT]);
    if (is_blank($c_tag_string) && !is_blank($c_tag_select) && $c_tag_select != 0) {
        $t_tag = tag_get($c_tag_select);
        $c_tag_string = $t_tag['name'];
    }
    if (!is_blank($c_tag_string)) {
        $t_tags = tag_parse_filters($c_tag_string);
        if (count($t_tags)) {
            $t_tags_all = array();
            $t_tags_any = array();
            $t_tags_none = array();
            foreach ($t_tags as $t_tag_row) {
                switch ($t_tag_row['filter']) {
                    case 1:
                        $t_tags_all[] = $t_tag_row;
                        break;
                    case 0:
                        $t_tags_any[] = $t_tag_row;
                        break;
                    case -1:
                        $t_tags_none[] = $t_tag_row;
                        break;
                }
            }
            if (0 < $t_filter[FILTER_PROPERTY_TAG_SELECT] && tag_exists($t_filter[FILTER_PROPERTY_TAG_SELECT])) {
                $t_tags_any[] = tag_get($t_filter[FILTER_PROPERTY_TAG_SELECT]);
            }
            if (count($t_tags_all)) {
                $t_clauses = array();
                foreach ($t_tags_all as $t_tag_row) {
                    array_push($t_clauses, '{bug}.id IN ( SELECT bug_id FROM {bug_tag} WHERE {bug_tag}.tag_id = ' . $t_tag_row['id'] . ')');
                }
                array_push($t_where_clauses, '(' . implode(' AND ', $t_clauses) . ')');
            }
            if (count($t_tags_any)) {
                $t_clauses = array();
                foreach ($t_tags_any as $t_tag_row) {
                    array_push($t_clauses, '{bug_tag}.tag_id = ' . $t_tag_row['id']);
                }
                array_push($t_where_clauses, '{bug}.id IN ( SELECT bug_id FROM {bug_tag} WHERE ( ' . implode(' OR ', $t_clauses) . ') )');
            }
            if (count($t_tags_none)) {
                $t_clauses = array();
                foreach ($t_tags_none as $t_tag_row) {
                    array_push($t_clauses, '{bug_tag}.tag_id = ' . $t_tag_row['id']);
                }
                array_push($t_where_clauses, '{bug}.id NOT IN ( SELECT bug_id FROM {bug_tag} WHERE ( ' . implode(' OR ', $t_clauses) . ') )');
            }
        }
    }
    # note user id
    if (!filter_field_is_any($t_filter[FILTER_PROPERTY_NOTE_USER_ID])) {
        $t_bugnote_table_alias = 'mbnt';
        $t_clauses = array();
        array_push($t_join_clauses, 'LEFT JOIN {bugnote} ' . $t_bugnote_table_alias . ' ON {bug}.id = ' . $t_bugnote_table_alias . '.bug_id');
        foreach ($t_filter[FILTER_PROPERTY_NOTE_USER_ID] as $t_filter_member) {
            $c_note_user_id = (int) $t_filter_member;
            if (filter_field_is_myself($c_note_user_id)) {
                array_push($t_clauses, $c_user_id);
            } else {
                array_push($t_clauses, $c_note_user_id);
            }
        }
        if (1 < count($t_clauses)) {
            $t_where_tmp = array();
            foreach ($t_clauses as $t_clause) {
                $t_where_tmp[] = db_param();
                $t_where_params[] = $t_clause;
            }
            array_push($t_where_clauses, '( ' . $t_bugnote_table_alias . '.reporter_id in (' . implode(', ', $t_where_tmp) . ') )');
        } else {
            $t_where_params[] = $t_clauses[0];
            array_push($t_where_clauses, '( ' . $t_bugnote_table_alias . '.reporter_id=' . db_param() . ' )');
        }
    }
    # plugin filters
    $t_plugin_filters = filter_get_plugin_filters();
    foreach ($t_plugin_filters as $t_field_name => $t_filter_object) {
        if (!filter_field_is_any($t_filter[$t_field_name]) || $t_filter_object->type == FILTER_TYPE_BOOLEAN) {
            $t_filter_query = $t_filter_object->query($t_filter[$t_field_name]);
            if (is_array($t_filter_query)) {
                if (isset($t_filter_query['join'])) {
                    array_push($t_join_clauses, $t_filter_query['join']);
                }
                if (isset($t_filter_query['where'])) {
                    array_push($t_where_clauses, $t_filter_query['where']);
                }
                if (isset($t_filter_query['params']) && is_array($t_filter_query['params'])) {
                    $t_where_params = array_merge($t_where_params, $t_filter_query['params']);
                }
            }
        }
    }
    # custom field filters
    if (ON == config_get('filter_by_custom_fields')) {
        # custom field filtering
        # @@@ At the moment this gets the linked fields relating to the current project
        #     It should get the ones relating to the project in the filter or all projects
        #     if multiple projects.
        $t_custom_fields = custom_field_get_linked_ids($t_project_id);
        foreach ($t_custom_fields as $t_cfid) {
            $t_field_info = custom_field_cache_row($t_cfid, true);
            if (!$t_field_info['filter_by']) {
                continue;
                # skip this custom field it shouldn't be filterable
            }
            $t_field = $t_filter['custom_fields'][$t_cfid];
            $t_custom_where_clause = '';
            # Ignore all custom filters that are not set, or that are set to '' or "any"
            if (!filter_field_is_any($t_field)) {
                $t_def = custom_field_get_definition($t_cfid);
                $t_table_name = '{custom_field_string}_' . $t_cfid;
                # We need to filter each joined table or the result query will explode in dimensions
                # Each custom field will result in a exponential growth like Number_of_Issues^Number_of_Custom_Fields
                # and only after this process ends (if it is able to) the result query will be filtered
                # by the WHERE clause and by the DISTINCT clause
                $t_cf_join_clause = 'LEFT JOIN {custom_field_string} ' . $t_table_name . ' ON {bug}.id = ' . $t_table_name . '.bug_id AND ' . $t_table_name . '.field_id = ' . $t_cfid;
                if ($t_def['type'] == CUSTOM_FIELD_TYPE_DATE) {
                    # Define the value field with type cast to integer
                    $t_value_field = 'CAST(COALESCE(NULLIF(' . $t_table_name . '.value, \'\'), \'0\') AS DECIMAL)';
                    switch ($t_field[0]) {
                        # Closing parenthesis intentionally omitted, will be added later on
                        case CUSTOM_FIELD_DATE_ANY:
                            break;
                        case CUSTOM_FIELD_DATE_NONE:
                            array_push($t_join_clauses, $t_cf_join_clause);
                            $t_custom_where_clause = '( ' . $t_table_name . '.bug_id is null OR ' . $t_value_field . ' = 0 ';
                            break;
                        case CUSTOM_FIELD_DATE_BEFORE:
                            array_push($t_join_clauses, $t_cf_join_clause);
                            $t_custom_where_clause = '( ' . $t_value_field . ' != 0 AND ' . $t_value_field . ' < ' . $t_field[2];
                            break;
                        case CUSTOM_FIELD_DATE_AFTER:
                            array_push($t_join_clauses, $t_cf_join_clause);
                            $t_custom_where_clause = '( ' . $t_value_field . ' > ' . ($t_field[1] + 1);
                            break;
                        default:
                            array_push($t_join_clauses, $t_cf_join_clause);
                            $t_custom_where_clause = '( ' . $t_value_field . ' BETWEEN ' . $t_field[1] . ' AND ' . $t_field[2];
                            break;
                    }
                } else {
                    array_push($t_join_clauses, $t_cf_join_clause);
                    $t_filter_array = array();
                    foreach ($t_field as $t_filter_member) {
                        $t_filter_member = stripslashes($t_filter_member);
                        if (filter_field_is_none($t_filter_member)) {
                            # coerce filter value if selecting META_FILTER_NONE so it will match empty fields
                            $t_filter_member = '';
                            # but also add those _not_ present in the custom field string table
                            array_push($t_filter_array, '{bug}.id NOT IN (SELECT bug_id FROM {custom_field_string} WHERE field_id=' . $t_cfid . ')');
                        }
                        switch ($t_def['type']) {
                            case CUSTOM_FIELD_TYPE_CHECKBOX:
                            case CUSTOM_FIELD_TYPE_MULTILIST:
                                $t_where_params[] = '%|' . $t_filter_member . '|%';
                                array_push($t_filter_array, db_helper_like($t_table_name . '.value'));
                                break;
                            case CUSTOM_FIELD_TYPE_TEXTAREA:
                                $t_where_params[] = '%' . $t_filter_member . '%';
                                array_push($t_filter_array, db_helper_like($t_table_name . '.text'));
                                break;
                            default:
                                $t_where_params[] = $t_filter_member;
                                array_push($t_filter_array, $t_table_name . '.value = ' . db_param());
                        }
                    }
                    $t_custom_where_clause .= '(' . implode(' OR ', $t_filter_array);
                }
                if (!is_blank($t_custom_where_clause)) {
                    array_push($t_where_clauses, $t_custom_where_clause . ')');
                }
            }
        }
    }
    # Text search
    if (!is_blank($t_filter[FILTER_PROPERTY_SEARCH])) {
        # break up search terms by spacing or quoting
        preg_match_all("/-?([^'\"\\s]+|\"[^\"]+\"|'[^']+')/", $t_filter[FILTER_PROPERTY_SEARCH], $t_matches, PREG_SET_ORDER);
        # organize terms without quoting, paying attention to negation
        $t_search_terms = array();
        foreach ($t_matches as $t_match) {
            $t_search_terms[trim($t_match[1], "\\'\"")] = $t_match[0][0] == '-';
        }
        # build a big where-clause and param list for all search terms, including negations
        $t_first = true;
        $t_textsearch_where_clause = '( ';
        foreach ($t_search_terms as $t_search_term => $t_negate) {
            if (!$t_first) {
                $t_textsearch_where_clause .= ' AND ';
            }
            if ($t_negate) {
                $t_textsearch_where_clause .= 'NOT ';
            }
            $c_search = '%' . $t_search_term . '%';
            $t_textsearch_where_clause .= '( ' . db_helper_like('{bug}.summary') . ' OR ' . db_helper_like('{bug_text}.description') . ' OR ' . db_helper_like('{bug_text}.steps_to_reproduce') . ' OR ' . db_helper_like('{bug_text}.additional_information') . ' OR ' . db_helper_like('{bugnote_text}.note');
            $t_where_params[] = $c_search;
            $t_where_params[] = $c_search;
            $t_where_params[] = $c_search;
            $t_where_params[] = $c_search;
            $t_where_params[] = $c_search;
            if (is_numeric($t_search_term)) {
                # PostgreSQL on 64-bit OS hack (see #14014)
                if (PHP_INT_MAX > 0x7fffffff && db_is_pgsql()) {
                    $t_search_max = 0x7fffffff;
                } else {
                    $t_search_max = PHP_INT_MAX;
                }
                # Note: no need to test negative values, '-' sign has been removed
                if ($t_search_term <= $t_search_max) {
                    $c_search_int = (int) $t_search_term;
                    $t_textsearch_where_clause .= ' OR {bug}.id = ' . db_param();
                    $t_textsearch_where_clause .= ' OR {bugnote}.id = ' . db_param();
                    $t_where_params[] = $c_search_int;
                    $t_where_params[] = $c_search_int;
                }
            }
            $t_textsearch_where_clause .= ' )';
            $t_first = false;
        }
        $t_textsearch_where_clause .= ' )';
        # add text query elements to arrays
        if (!$t_first) {
            $t_join_clauses[] = 'JOIN {bug_text} ON {bug}.bug_text_id = {bug_text}.id';
            $t_join_clauses[] = 'LEFT JOIN {bugnote} ON {bug}.id = {bugnote}.bug_id';
            # Outer join required otherwise we don't retrieve issues without notes
            $t_join_clauses[] = 'LEFT JOIN {bugnote_text} ON {bugnote}.bugnote_text_id = {bugnote_text}.id';
            $t_where_clauses[] = $t_textsearch_where_clause;
        }
    }
    # End text search
    # Determine join operator
    if ($t_filter[FILTER_PROPERTY_MATCH_TYPE] == FILTER_MATCH_ANY) {
        $t_join_operator = ' OR ';
    } else {
        $t_join_operator = ' AND ';
    }
    log_event(LOG_FILTERING, 'Join operator : ' . $t_join_operator);
    $t_query_clauses['select'] = $t_select_clauses;
    $t_query_clauses['from'] = $t_from_clauses;
    $t_query_clauses['join'] = $t_join_clauses;
    $t_query_clauses['where'] = $t_where_clauses;
    $t_query_clauses['where_values'] = $t_where_params;
    $t_query_clauses['project_where'] = $t_project_where_clauses;
    $t_query_clauses['operator'] = $t_join_operator;
    $t_query_clauses = filter_get_query_sort_data($t_filter, $p_show_sticky, $t_query_clauses);
    # assigning to $p_* for this function writes the values back in case the caller wants to know
    # Get the total number of bugs that meet the criteria.
    $p_bug_count = filter_get_bug_count($t_query_clauses);
    if (0 == $p_bug_count) {
        return array();
    }
    $p_per_page = filter_per_page($t_filter, $p_bug_count, $p_per_page);
    $p_page_count = filter_page_count($p_bug_count, $p_per_page);
    $p_page_number = filter_valid_page_number($p_page_number, $p_page_count);
    $t_offset = filter_offset($p_page_number, $p_per_page);
    $t_query_clauses = filter_unique_query_clauses($t_query_clauses);
    $t_select_string = 'SELECT DISTINCT ' . implode(', ', $t_query_clauses['select']);
    $t_from_string = ' FROM ' . implode(', ', $t_query_clauses['from']);
    $t_order_string = ' ORDER BY ' . implode(', ', $t_query_clauses['order']);
    $t_join_string = count($t_query_clauses['join']) > 0 ? implode(' ', $t_query_clauses['join']) : ' ';
    $t_where_string = ' WHERE ' . implode(' AND ', $t_query_clauses['project_where']);
    if (count($t_query_clauses['where']) > 0) {
        $t_where_string .= ' AND ( ';
        $t_where_string .= implode($t_join_operator, $t_query_clauses['where']);
        $t_where_string .= ' ) ';
    }
    $t_result = db_query($t_select_string . $t_from_string . $t_join_string . $t_where_string . $t_order_string, $t_query_clauses['where_values'], $p_per_page, $t_offset);
    $t_id_array_lastmod = array();
    while ($t_row = db_fetch_array($t_result)) {
        $t_id_array_lastmod[] = (int) $t_row['id'];
        $t_rows[] = $t_row;
    }
    return filter_cache_result($t_rows, $t_id_array_lastmod);
}
Example #28
0
		</thead>
		<?php 
summary_print_reporter_resolution(config_get('resolution_enum_string'));
?>
	</table>

	<!-- DEVELOPER BY RESOLUTION -->
	<table>
		<thead>
			<tr class="row-category2">
				<th><?php 
echo lang_get('developer_by_resolution');
?>
</th>
				<?php 
$t_resolutions = MantisEnum::getValues(config_get('resolution_enum_string'));
foreach ($t_resolutions as $t_resolution) {
    echo '<td class="right">', get_enum_element('resolution', $t_resolution), "</td>\n";
}
echo '<td class="right">', lang_get('percentage_fixed'), "</td>\n";
?>
			</tr>
		</thead>
		<?php 
summary_print_developer_resolution(config_get('resolution_enum_string'));
?>
	</table>

</div>

</div>
Example #29
0
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>';
    }
}
$t_redirect_url = 'manage_config_email_page.php';
$t_project = helper_get_current_project();
$f_flags = gpc_get('flag', array());
$f_thresholds = gpc_get('flag_threshold', array());
$f_actions_access = gpc_get_int('notify_actions_access');
html_page_top(lang_get('manage_email_config'), $t_redirect_url);
$t_access = current_user_get_access_level();
$t_can_change_flags = $t_access >= config_get_access('notify_flags');
$t_can_change_defaults = $t_access >= config_get_access('default_notify_flags');
# build a list of the possible actions and flags
$t_valid_actions = array('owner', 'reopened', 'deleted', 'bugnote');
if (config_get('enable_sponsorship') == ON) {
    $t_valid_actions[] = 'sponsor';
}
$t_valid_actions[] = 'relation';
$t_statuses = MantisEnum::getAssocArrayIndexedByValues(config_get('status_enum_string'));
ksort($t_statuses);
reset($t_statuses);
foreach ($t_statuses as $t_status => $t_label) {
    $t_valid_actions[] = $t_label;
}
$t_valid_flags = array('reporter', 'handler', 'monitor', 'bugnotes');
# initialize the thresholds
foreach ($t_valid_actions as $t_action) {
    $t_thresholds_min[$t_action] = NOBODY;
    $t_thresholds_max[$t_action] = ANYBODY;
}
# parse flags and thresholds
foreach ($f_flags as $t_flag_value) {
    list($t_action, $t_flag) = explode(':', $t_flag_value);
    $t_flags[$t_action][$t_flag] = ON;