예제 #1
0
/**
 * Creates and executes a query for the history rows related to bugs matched by the provided filter
 * @param  array $p_filter           Filter array
 * @param  integer $p_start_time     The start time to filter by, or null for all.
 * @param  integer $p_end_time       The end time to filter by, or null for all.
 * @param  string  $p_history_order  The sort order.
 * @return database result to pass into history_get_event_from_row().
 */
function history_get_range_result_filter($p_filter, $p_start_time = null, $p_end_time = null, $p_history_order = null)
{
    if ($p_history_order === null) {
        $t_history_order = config_get('history_order');
    } else {
        $t_history_order = $p_history_order;
    }
    # Note: filter_get_bug_rows_query_clauses() calls db_param_push();
    $t_query_clauses = filter_get_bug_rows_query_clauses($p_filter, null, null, null);
    # if the query can't be formed, there are no results
    if (empty($t_query_clauses)) {
        # reset the db_param stack that was initialized by "filter_get_bug_rows_query_clauses()"
        db_param_pop();
        return db_empty_result();
    }
    $t_select_string = 'SELECT DISTINCT {bug}.id ';
    $t_from_string = ' FROM ' . implode(', ', $t_query_clauses['from']);
    $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_query_clauses['operator'], $t_query_clauses['where']);
        $t_where_string .= ' ) ';
    }
    $t_query = 'SELECT * FROM {bug_history} JOIN' . ' ( ' . $t_select_string . $t_from_string . $t_join_string . $t_where_string . ' ) B' . ' ON {bug_history}.bug_id=B.id';
    $t_params = $t_query_clauses['where_values'];
    $t_where = array();
    if ($p_start_time !== null) {
        $t_where[] = 'date_modified >= ' . db_param();
        $t_params[] = $p_start_time;
    }
    if ($p_end_time !== null) {
        $t_where[] = 'date_modified < ' . db_param();
        $t_params[] = $p_end_time;
    }
    if (count($t_where) > 0) {
        $t_query .= ' WHERE ' . implode(' AND ', $t_where);
    }
    $t_query .= ' ORDER BY {bug_history}.date_modified ' . $t_history_order . ', {bug_history}.id ' . $t_history_order;
    $t_result = db_query($t_query, $t_params);
    return $t_result;
}
예제 #2
0
/**
 * Move any attachments as needed when a bug is moved from project to project.
 *
 * @param integer $p_bug_id        ID of bug containing attachments to be moved.
 * @param integer $p_project_id_to Destination project ID for the bug.
 * @return void
 *
 * @todo: this function can't cope with source or target storing attachments in DB
 */
function file_move_bug_attachments($p_bug_id, $p_project_id_to)
{
    $t_project_id_from = bug_get_field($p_bug_id, 'project_id');
    if ($t_project_id_from == $p_project_id_to) {
        return;
    }
    $t_method = config_get('file_upload_method');
    if ($t_method != DISK) {
        return;
    }
    if (!file_bug_has_attachments($p_bug_id)) {
        return;
    }
    $t_path_from = project_get_field($t_project_id_from, 'file_path');
    if (is_blank($t_path_from)) {
        $t_path_from = config_get('absolute_path_default_upload_folder', null, null, $t_project_id_from);
    }
    file_ensure_valid_upload_path($t_path_from);
    $t_path_to = project_get_field($p_project_id_to, 'file_path');
    if (is_blank($t_path_to)) {
        $t_path_to = config_get('absolute_path_default_upload_folder', null, null, $p_project_id_to);
    }
    file_ensure_valid_upload_path($t_path_to);
    if ($t_path_from == $t_path_to) {
        return;
    }
    # Initialize the update query to update a single row
    $c_bug_id = (int) $p_bug_id;
    db_param_push();
    $t_query_disk_attachment_update = 'UPDATE {bug_file}
	                                 SET folder=' . db_param() . '
	                                 WHERE bug_id=' . db_param() . '
	                                 AND id =' . db_param();
    $t_attachment_rows = bug_get_attachments($p_bug_id);
    $t_attachments_count = count($t_attachment_rows);
    for ($i = 0; $i < $t_attachments_count; $i++) {
        $t_row = $t_attachment_rows[$i];
        $t_basename = basename($t_row['diskfile']);
        $t_disk_file_name_from = file_path_combine($t_path_from, $t_basename);
        $t_disk_file_name_to = file_path_combine($t_path_to, $t_basename);
        if (!file_exists($t_disk_file_name_to)) {
            chmod($t_disk_file_name_from, 0775);
            if (!rename($t_disk_file_name_from, $t_disk_file_name_to)) {
                if (!copy($t_disk_file_name_from, $t_disk_file_name_to)) {
                    trigger_error(ERROR_FILE_MOVE_FAILED, ERROR);
                }
                file_delete_local($t_disk_file_name_from);
            }
            chmod($t_disk_file_name_to, config_get('attachments_file_permissions'));
            # Don't pop the parameters after query execution since we're in a loop
            db_query($t_query_disk_attachment_update, array(db_prepare_string($t_path_to), $c_bug_id, (int) $t_row['id']), false);
        } else {
            trigger_error(ERROR_FILE_DUPLICATE, ERROR);
        }
    }
    db_param_pop();
}
예제 #3
0
/**
 * Gets the candidates for the specified bug.  These are existing tags
 * that are not associated with the bug already.
 *
 * @param integer $p_bug_id The bug id, if 0 returns all tags.
 * @return array The array of tag rows, each with id, name, and description.
 */
function tag_get_candidates_for_bug($p_bug_id)
{
    db_param_push();
    $t_params = array();
    if (0 != $p_bug_id) {
        $t_params[] = $p_bug_id;
        if (config_get_global('db_type') == 'odbc_mssql') {
            db_param_push();
            $t_query = 'SELECT t.id FROM {tag} t
					LEFT JOIN {bug_tag} b ON t.id=b.tag_id
					WHERE b.bug_id IS NULL OR b.bug_id != ' . db_param();
            $t_result = db_query($t_query, $t_params);
            $t_params = null;
            $t_subquery_results = array();
            while ($t_row = db_fetch_array($t_result)) {
                $t_subquery_results[] = (int) $t_row['id'];
            }
            if (count($t_subquery_results) == 0) {
                db_param_pop();
                return array();
            }
            $t_query = 'SELECT id, name, description FROM {tag} WHERE id IN ( ' . implode(', ', $t_subquery_results) . ')';
        } else {
            $t_query = 'SELECT id, name, description FROM {tag} WHERE id IN (
					SELECT t.id FROM {tag} t
					LEFT JOIN {bug_tag} b ON t.id=b.tag_id
					WHERE b.bug_id IS NULL OR b.bug_id != ' . db_param() . ')';
        }
    } else {
        $t_query = 'SELECT id, name, description FROM {tag}';
    }
    $t_query .= ' ORDER BY name ASC ';
    $t_result = db_query($t_query, $t_params);
    $t_results_to_return = array();
    while ($t_row = db_fetch_array($t_result)) {
        $t_results_to_return[] = $t_row;
    }
    return $t_results_to_return;
}
예제 #4
0
/**
 * Update the field definition
 * return true on success, false on failure
 * @param integer $p_field_id  Custom field identifier.
 * @param array   $p_def_array Custom field definition.
 * @return boolean
 * @access public
 */
function custom_field_update($p_field_id, array $p_def_array)
{
    if (is_blank($p_def_array['name'])) {
        error_parameters('name');
        trigger_error(ERROR_EMPTY_FIELD, ERROR);
    }
    if ($p_def_array['access_level_rw'] < $p_def_array['access_level_r']) {
        error_parameters(lang_get('custom_field_access_level_r') . ', ' . lang_get('custom_field_access_level_rw'));
        trigger_error(ERROR_CUSTOM_FIELD_INVALID_PROPERTY, ERROR);
    }
    if ($p_def_array['length_min'] < 0 || $p_def_array['length_max'] != 0 && $p_def_array['length_min'] > $p_def_array['length_max']) {
        error_parameters(lang_get('custom_field_length_min') . ', ' . lang_get('custom_field_length_max'));
        trigger_error(ERROR_CUSTOM_FIELD_INVALID_PROPERTY, ERROR);
    }
    if (!custom_field_is_name_unique($p_def_array['name'], $p_field_id)) {
        trigger_error(ERROR_CUSTOM_FIELD_NAME_NOT_UNIQUE, ERROR);
    }
    db_param_push();
    # Build fields update statement
    $t_update = '';
    foreach ($p_def_array as $t_field => $t_value) {
        switch ($t_field) {
            case 'name':
            case 'possible_values':
            case 'default_value':
            case 'valid_regexp':
                # Possible values doesn't apply to textarea fields
                if ($p_def_array['type'] == CUSTOM_FIELD_TYPE_TEXTAREA && $t_field == 'possible_values') {
                    $t_value = '';
                }
                $t_update .= $t_field . '=' . db_param() . ', ';
                $t_params[] = (string) $t_value;
                break;
            case 'type':
            case 'access_level_r':
            case 'access_level_rw':
            case 'length_min':
            case 'length_max':
                $t_update .= $t_field . '=' . db_param() . ', ';
                $t_params[] = (int) $t_value;
                break;
            case 'filter_by':
            case 'display_report':
            case 'display_update':
            case 'display_resolved':
            case 'display_closed':
            case 'require_report':
            case 'require_update':
            case 'require_resolved':
            case 'require_closed':
                $t_update .= $t_field . '=' . db_param() . ', ';
                $t_params[] = (bool) $t_value;
                break;
        }
    }
    # If there are fields to update, execute SQL
    if ($t_update !== '') {
        $t_query = 'UPDATE {custom_field} SET ' . rtrim($t_update, ', ') . ' WHERE id = ' . db_param();
        $t_params[] = $p_field_id;
        db_query($t_query, $t_params);
        custom_field_clear_cache($p_field_id);
        return true;
    }
    # Reset the parameter count manually since the query was not executed
    db_param_pop();
    return false;
}
예제 #5
0
/**
 * Creates a sql query with the supplied filter query clauses, and returns the unprocessed result set opbject
 *
 * Note: The parameter $p_pop_param can be used as 'false' to keep db_params in the stack,
 * if the same query clauses object is reused for several queries. In that case a db_param_pop()
 * should be used manually when required.
 * This is the case when "filter_get_bug_count" is used followed by "filter_get_bug_rows_result"
 * @param array   $p_query_clauses Array of query clauses
 * @param integer $p_count         The number of rows to return
 *                                 -1 or null indicates default query (no limits)
 * @param integer $p_offset        Offset query results for paging (number of rows)
 *                                 -1 or null indicates default query (no offset)
 * @param boolean $p_pop_param        Whether to pop DB params from the stack
 * @return IteratorAggregate|boolean adodb result set or false if the query failed.
 */
function filter_get_bug_rows_result(array $p_query_clauses, $p_count = null, $p_offset = null, $p_pop_param = true)
{
    # if the query can't be formed, there are no results
    if (empty($p_query_clauses)) {
        if ($p_pop_param) {
            # reset the db_param stack, this woould have been done by db_query if executed
            db_param_pop();
        }
        return db_empty_result();
    }
    if (null === $p_count) {
        $t_count = -1;
    } else {
        $t_count = $p_count;
    }
    if (null === $p_offset) {
        $t_offset = -1;
    } else {
        $t_offset = $p_offset;
    }
    $t_query_clauses = $p_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_query_clauses['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'], $t_count, $t_offset, $p_pop_param);
    return $t_result;
}
/**
 * Migrate the legacy date format.
 * @param array $p_data Array: [0] = tablename, [1] id column, [2] = old column, [3] = new column.
 * @return integer
 */
function install_date_migrate(array $p_data)
{
    # $p_data[0] = tablename, [1] id column, [2] = old column, [3] = new column
    # Disable query logging even if enabled in config, due to possibility of mass spam
    $t_log_queries = install_set_log_queries();
    $t_table = $p_data[0];
    $t_id_column = $p_data[1];
    $t_date_array = is_array($p_data[2]);
    if ($t_date_array) {
        $t_old_column = implode(',', $p_data[2]);
        $t_cnt_fields = count($p_data[2]);
        $t_query = 'SELECT ' . $t_id_column . ', ' . $t_old_column . ' FROM ' . $t_table;
        $t_first_column = true;
        # In order to handle large databases where we may timeout during the upgrade, we don't
        # start from the beginning everytime.  Here we will only pickup rows where at least one
        # of the datetime fields wasn't upgraded yet and upgrade them all.
        foreach ($p_data[3] as $t_new_column_name) {
            if ($t_first_column) {
                $t_first_column = false;
                $t_query .= ' WHERE ';
            } else {
                $t_query .= ' OR ';
            }
            $t_query .= $t_new_column_name . ' = 1';
        }
    } else {
        $t_old_column = $p_data[2];
        # The check for timestamp being = 1 is to make sure the field wasn't upgraded
        # already in a previous run - see bug #12601 for more details.
        $t_new_column_name = $p_data[3];
        $t_query = 'SELECT ' . $t_id_column . ', ' . $t_old_column . ' FROM ' . $t_table . ' WHERE ' . $t_new_column_name . ' = 1';
    }
    $t_result = db_query($t_query);
    if (db_num_rows($t_result) > 0) {
        db_param_push();
        # Build the update query
        if ($t_date_array) {
            $t_pairs = array();
            foreach ($p_data[3] as $t_var) {
                array_push($t_pairs, $t_var . '=' . db_param());
            }
            $t_new_column = implode(',', $t_pairs);
        } else {
            $t_new_column = $p_data[3] . '=' . db_param();
        }
        $t_query = 'UPDATE ' . $t_table . ' SET ' . $t_new_column . ' WHERE ' . $t_id_column . '=' . db_param();
        while ($t_row = db_fetch_array($t_result)) {
            $t_id = (int) $t_row[$t_id_column];
            if ($t_date_array) {
                for ($i = 0; $i < $t_cnt_fields; $i++) {
                    $t_old_value = $t_row[$p_data[2][$i]];
                    if (is_numeric($t_old_value)) {
                        return 1;
                        # Fatal: conversion may have already been run. If it has been run, proceeding will wipe timestamps from db
                    }
                    $t_new_value[$i] = db_unixtimestamp($t_old_value);
                    if ($t_new_value[$i] < 100000) {
                        $t_new_value[$i] = 1;
                    }
                }
                $t_values = $t_new_value;
                $t_values[] = $t_id;
            } else {
                $t_old_value = $t_row[$t_old_column];
                if (is_numeric($t_old_value)) {
                    return 1;
                    # Fatal: conversion may have already been run. If it has been run, proceeding will wipe timestamps from db
                }
                $t_new_value = db_unixtimestamp($t_old_value);
                if ($t_new_value < 100000) {
                    $t_new_value = 1;
                }
                $t_values = array($t_new_value, $t_id);
            }
            # Don't pop params since we're in a loop
            db_query($t_query, $t_values, -1, -1, false);
        }
        db_param_pop();
    }
    # Re-enable query logging if we disabled it
    install_set_log_queries($t_log_queries);
    # return 2 because that's what ADOdb/DataDict does when things happen properly
    return 2;
}