/** * Gets the billing information for the specified project during the specified date range. * * @param integer $p_project_id A project identifier or ALL_PROJECTS. * @param string $p_from Starting date (yyyy-mm-dd) inclusive, if blank, then ignored. * @param string $p_to Ending date (yyyy-mm-dd) inclusive, if blank, then ignored. * @param integer $p_cost_per_hour Cost per hour. * @return array array of bugnotes * @access public */ function billing_get_for_project($p_project_id, $p_from, $p_to, $p_cost_per_hour) { $t_params = array(); $c_to = strtotime($p_to) + SECONDS_PER_DAY - 1; $c_from = strtotime($p_from); if ($c_to === false || $c_from === false) { error_parameters(array($p_from, $p_to)); trigger_error(ERROR_GENERIC, ERROR); } db_param_push(); if (ALL_PROJECTS != $p_project_id) { access_ensure_project_level(config_get('view_bug_threshold'), $p_project_id); $t_project_where = ' AND b.project_id = ' . db_param() . ' AND bn.bug_id = b.id '; $t_params[] = $p_project_id; } else { $t_project_ids = user_get_all_accessible_projects(); $t_project_where = ' AND b.project_id in (' . implode(', ', $t_project_ids) . ')'; } if (!is_blank($c_from)) { $t_from_where = ' AND bn.date_submitted >= ' . db_param(); $t_params[] = $c_from; } else { $t_from_where = ''; } if (!is_blank($c_to)) { $t_to_where = ' AND bn.date_submitted <= ' . db_param(); $t_params[] = $c_to; } else { $t_to_where = ''; } $t_results = array(); $t_query = 'SELECT bn.id id, bn.time_tracking minutes, bn.date_submitted as date_submitted, bnt.note note, u.realname realname, b.project_id project_id, c.name bug_category, b.summary bug_summary, bn.bug_id bug_id, bn.reporter_id reporter_id FROM {user} u, {bugnote} bn, {bug} b, {bugnote_text} bnt, {category} c WHERE u.id = bn.reporter_id AND bn.time_tracking != 0 AND bn.bug_id = b.id AND bnt.id = bn.bugnote_text_id AND c.id=b.category_id ' . $t_project_where . $t_from_where . $t_to_where . ' ORDER BY bn.id'; $t_result = db_query($t_query, $t_params); $t_cost_per_min = $p_cost_per_hour / 60.0; $t_access_level_required = config_get('time_tracking_view_threshold'); while ($t_row = db_fetch_array($t_result)) { if (!access_has_bugnote_level($t_access_level_required, $t_row['id'])) { continue; } $t_total_cost = $t_cost_per_min * $t_row['minutes']; $t_row['cost'] = $t_total_cost; $t_results[] = $t_row; } $t_billing_rows = billing_rows_to_array($t_results); return $t_billing_rows; }
/** * Revokes the api token with the specified id * @param integer $p_api_token_id The API token id. * @param integer $p_user_id The user id. * @return void * @access public */ function api_token_revoke($p_api_token_id, $p_user_id) { db_param_push(); $t_query = 'DELETE FROM {api_token} WHERE id=' . db_param() . ' AND user_id = ' . db_param(); db_query($t_query, array($p_api_token_id, $p_user_id)); }
/** * Return an array of ids of custom fields bound to the specified project * * The ids will be sorted based on the sequence number associated with the binding * @param integer $p_project_id A project identifier. * @return array * @access public */ function custom_field_get_linked_ids($p_project_id = ALL_PROJECTS) { global $g_cache_cf_linked; if (!isset($g_cache_cf_linked[$p_project_id])) { db_param_push(); if (ALL_PROJECTS == $p_project_id) { $t_user_id = auth_get_current_user_id(); # Select only the ids of custom fields in projects the user has access to # - all custom fields in public projects, # - those in private projects where the user is listed # - in private projects where the user is implicitly listed $t_query = 'SELECT DISTINCT cft.id FROM {custom_field} cft JOIN {custom_field_project} cfpt ON cfpt.field_id = cft.id JOIN {project} pt ON pt.id = cfpt.project_id AND pt.enabled = ' . db_prepare_bool(true) . ' LEFT JOIN {project_user_list} pult ON pult.project_id = cfpt.project_id AND pult.user_id = ' . db_param() . ' , {user} ut WHERE ut.id = ' . db_param() . ' AND ( pt.view_state = ' . VS_PUBLIC . ' OR pult.user_id = ut.id '; $t_params = array($t_user_id, $t_user_id); # Add private access clause and related parameter $t_private_access = config_get('private_project_threshold'); if (is_array($t_private_access)) { if (1 == count($t_private_access)) { $t_access_clause = '= ' . db_param(); $t_params[] = array_shift($t_private_access); } else { $t_access_clause = 'IN ('; foreach ($t_private_access as $t_elem) { $t_access_clause .= db_param() . ','; $t_params[] = $t_elem; } $t_access_clause = rtrim($t_access_clause, ',') . ')'; } } else { $t_access_clause = '>=' . db_param(); $t_params[] = $t_private_access; } $t_query .= 'OR ( pult.user_id IS NULL AND ut.access_level ' . $t_access_clause . ' ) )'; } else { if (is_array($p_project_id)) { if (1 == count($p_project_id)) { $t_project_clause = '= ' . db_param(); $t_params[] = array_shift($p_project_id); } else { $t_project_clause = 'IN ('; foreach ($p_project_id as $t_project) { $t_project_clause .= db_param() . ','; $t_params[] = $t_project; } $t_project_clause = rtrim($t_project_clause, ',') . ')'; } } else { $t_project_clause = '= ' . db_param(); $t_params[] = $p_project_id; } $t_query = 'SELECT cft.id FROM {custom_field} cft JOIN {custom_field_project} cfpt ON cfpt.field_id = cft.id WHERE cfpt.project_id ' . $t_project_clause . ' ORDER BY sequence ASC, name ASC'; } $t_result = db_query($t_query, $t_params); $t_ids = array(); while ($t_row = db_fetch_array($t_result)) { array_push($t_ids, $t_row['id']); } custom_field_cache_array_rows($t_ids); $g_cache_cf_linked[$p_project_id] = $t_ids; } else { $t_ids = $g_cache_cf_linked[$p_project_id]; } return $t_ids; }
/** * Prepare possible values for option list * @param array $p_field_def Custom field definition. * @return array|boolean */ function cfdef_prepare_list_distinct_values(array $p_field_def) { db_param_push(); $t_query = 'SELECT possible_values FROM {custom_field} WHERE id=' . db_param(); $t_result = db_query($t_query, array($p_field_def['id'])); $t_row = db_fetch_array($t_result); if (!$t_row) { return false; } $t_possible_values = custom_field_prepare_possible_values($t_row['possible_values']); $t_values_arr = explode('|', $t_possible_values); $t_return_arr = array(); foreach ($t_values_arr as $t_option) { array_push($t_return_arr, $t_option); } return $t_return_arr; }
/** * Retrieve user id of current user * @return integer user id * @access public */ function auth_get_current_user_id() { global $g_cache_current_user_id; if (null !== $g_cache_current_user_id) { return $g_cache_current_user_id; } $t_cookie_string = auth_get_current_user_cookie(); if ($t_result = user_search_cache('cookie_string', $t_cookie_string)) { $t_user_id = (int) $t_result['id']; current_user_set($t_user_id); return $t_user_id; } # @todo error with an error saying they aren't logged in? Or redirect to the login page maybe? db_param_push(); $t_query = 'SELECT id FROM {user} WHERE cookie_string=' . db_param(); $t_result = db_query($t_query, array($t_cookie_string)); $t_user_id = (int) db_result($t_result); # The cookie was invalid. Clear the cookie (to allow people to log in again) # and give them an Access Denied message. if (!$t_user_id) { auth_clear_cookies(); access_denied(); exit; } current_user_set($t_user_id); return $t_user_id; }
/** * Find and register all installed plugins. * This includes the MantisCore pseudo-plugin. * @return void */ function plugin_register_installed() { global $g_plugin_cache_priority, $g_plugin_cache_protected; # register plugins specified in the site configuration foreach (plugin_get_force_installed() as $t_basename => $t_priority) { plugin_register($t_basename); $g_plugin_cache_priority[$t_basename] = $t_priority; $g_plugin_cache_protected[$t_basename] = true; } # register plugins installed via the interface/database db_param_push(); $t_query = 'SELECT basename, priority, protected FROM {plugin} WHERE enabled=' . db_param() . ' ORDER BY priority DESC'; $t_result = db_query($t_query, array(true)); while ($t_row = db_fetch_array($t_result)) { $t_basename = $t_row['basename']; if (!plugin_is_registered($t_basename)) { plugin_register($t_basename); $g_plugin_cache_priority[$t_basename] = (int) $t_row['priority']; $g_plugin_cache_protected[$t_basename] = (bool) $t_row['protected']; } } }
/** * Cache project hierarchy * @param boolean $p_show_disabled Whether or not to cache projects which are disabled. * @return void */ function project_hierarchy_cache($p_show_disabled = false) { global $g_cache_project_hierarchy, $g_cache_project_inheritance; global $g_cache_show_disabled; if (!is_null($g_cache_project_hierarchy) && $g_cache_show_disabled == $p_show_disabled) { return; } $g_cache_show_disabled = $p_show_disabled; db_param_push(); $t_enabled_clause = $p_show_disabled ? '1=1' : 'p.enabled = ' . db_param(); $t_query = 'SELECT DISTINCT p.id, ph.parent_id, p.name, p.inherit_global, ph.inherit_parent FROM {project} p LEFT JOIN {project_hierarchy} ph ON ph.child_id = p.id WHERE ' . $t_enabled_clause . ' ORDER BY p.name'; $t_result = db_query($t_query, $p_show_disabled ? array() : array(true)); $g_cache_project_hierarchy = array(); $g_cache_project_inheritance = array(); while ($t_row = db_fetch_array($t_result)) { if (null === $t_row['parent_id']) { $t_row['parent_id'] = ALL_PROJECTS; } if (isset($g_cache_project_hierarchy[(int) $t_row['parent_id']])) { $g_cache_project_hierarchy[(int) $t_row['parent_id']][] = (int) $t_row['id']; } else { $g_cache_project_hierarchy[(int) $t_row['parent_id']] = array((int) $t_row['id']); } if (!isset($g_cache_project_inheritance[(int) $t_row['id']])) { $g_cache_project_inheritance[(int) $t_row['id']] = array(); } if ($t_row['inherit_global'] && !isset($g_cache_project_inheritance[(int) $t_row['id']][ALL_PROJECTS])) { $g_cache_project_inheritance[(int) $t_row['id']][] = ALL_PROJECTS; } if ($t_row['inherit_parent'] && !isset($g_cache_project_inheritance[(int) $t_row['id']][(int) $t_row['parent_id']])) { $g_cache_project_inheritance[(int) $t_row['id']][] = (int) $t_row['parent_id']; } } }
/** * Purge all expired tokens. * @param integer $p_token_type The token type. * @return boolean always true. */ function token_purge_expired($p_token_type = null) { global $g_tokens_purged; db_param_push(); $t_query = 'DELETE FROM {tokens} WHERE ' . db_param() . ' > expiry'; if (!is_null($p_token_type)) { $t_query .= ' AND type=' . db_param(); db_query($t_query, array(db_now(), (int) $p_token_type)); } else { db_query($t_query, array(db_now())); } $g_tokens_purged = true; return true; }
/** * Get a list of related tags. * Returns a list of tags that are the most related to the given tag, * based on the number of times they have been attached to the same bugs. * Defaults to a list of five tags. * @param integer $p_tag_id The tag ID to retrieve statistics on. * @param integer $p_limit List size. * @return array Array of tag rows, with share count added */ function tag_stats_related($p_tag_id, $p_limit = 5) { $c_user_id = auth_get_current_user_id(); db_param_push(); $t_subquery = 'SELECT b.id FROM {bug} b LEFT JOIN {project_user_list} p ON p.project_id=b.project_id AND p.user_id=' . db_param() . ' JOIN {user} u ON u.id=' . db_param() . ' JOIN {bug_tag} t ON t.bug_id=b.id WHERE ( p.access_level>b.view_state OR u.access_level>b.view_state ) AND t.tag_id=' . db_param(); # 4th Param $t_query = 'SELECT * FROM {bug_tag} WHERE tag_id != ' . db_param() . ' AND bug_id IN ( ' . $t_subquery . ' ) '; $t_result = db_query($t_query, array($p_tag_id, $c_user_id, $c_user_id, $p_tag_id)); $t_tag_counts = array(); while ($t_row = db_fetch_array($t_result)) { if (!isset($t_tag_counts[$t_row['tag_id']])) { $t_tag_counts[$t_row['tag_id']] = 1; } else { $t_tag_counts[$t_row['tag_id']]++; } } arsort($t_tag_counts); $t_tags = array(); $i = 1; foreach ($t_tag_counts as $t_tag_id => $t_count) { $t_tag_row = tag_get($t_tag_id); $t_tag_row['count'] = $t_count; $t_tags[] = $t_tag_row; $i++; if ($i > $p_limit) { break; } } return $t_tags; }
/** * Update a bug from the given data structure * If the third parameter is true, also update the longer strings table * @param boolean $p_update_extended Whether to update extended fields. * @param boolean $p_bypass_mail Whether to bypass sending email notifications. * @internal param boolean $p_bypass_email Default false, set to true to avoid generating emails (if sending elsewhere) * @return boolean (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); # 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() db_param_push(); $t_query = 'UPDATE {bug} SET project_id=' . db_param() . ', reporter_id=' . db_param() . ', handler_id=' . db_param() . ', duplicate_id=' . db_param() . ', priority=' . db_param() . ', severity=' . db_param() . ', reproducibility=' . db_param() . ', status=' . db_param() . ', resolution=' . db_param() . ', projection=' . db_param() . ', category_id=' . db_param() . ', eta=' . db_param() . ', os=' . db_param() . ', os_build=' . db_param() . ', platform=' . db_param() . ', version=' . db_param() . ', build=' . 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'))) { $t_query .= ' target_version=' . db_param() . ','; $t_fields[] = $this->target_version; $t_roadmap_updated = true; } $t_query .= ' view_state=' . db_param() . ', summary=' . db_param() . ', sponsorship_total=' . db_param() . ', sticky=' . db_param() . ', due_date=' . db_param() . ' WHERE 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($t_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_id = bug_get_field($c_bug_id, 'bug_text_id'); db_param_push(); $t_query = 'UPDATE {bug_text} SET description=' . db_param() . ', steps_to_reproduce=' . db_param() . ', additional_information=' . db_param() . ' WHERE id=' . db_param(); db_query($t_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) { 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) { 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) { 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) { # If handler changes, send out owner change email if ($t_old_data->handler_id != $this->handler_id) { email_owner_changed($c_bug_id, $t_old_data->handler_id, $this->handler_id); 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_bug_status_changed($c_bug_id, $t_status); return true; } # @todo handle priority change if it requires special handling email_bug_updated($c_bug_id); } return true; }
/** * Sets the sequence number for the specified custom field for the specified * project. * @param integer $p_field_id A custom field identifier. * @param integer $p_project_id A Project identifier. * @param integer $p_sequence Sequence order. * @return boolean * @access public */ function custom_field_set_sequence($p_field_id, $p_project_id, $p_sequence) { db_param_push(); $t_query = 'UPDATE {custom_field_project} SET sequence=' . db_param() . ' WHERE field_id=' . db_param() . ' AND project_id=' . db_param(); db_query($t_query, array($p_sequence, $p_field_id, $p_project_id)); custom_field_clear_cache($p_field_id); return true; }
/** * Note: any changes made in this function should be reflected in * mci_filter_db_get_available_queries()) * @param integer $p_project_id A valid project identifier. * @param integer $p_user_id A valid user identifier. * @return mixed */ function filter_db_get_available_queries($p_project_id = null, $p_user_id = null) { $t_overall_query_arr = array(); if (null === $p_project_id) { $t_project_id = helper_get_current_project(); } else { $t_project_id = (int) $p_project_id; } if (null === $p_user_id) { $t_user_id = auth_get_current_user_id(); } else { $t_user_id = (int) $p_user_id; } # If the user doesn't have access rights to stored queries, just return if (!access_has_project_level(config_get('stored_query_use_threshold'))) { return $t_overall_query_arr; } # Get the list of available queries. By sorting such that public queries are # first, we can override any query that has the same name as a private query # with that private one db_param_push(); $t_query = 'SELECT * FROM {filters} WHERE (project_id=' . db_param() . ' OR project_id=0) AND name!=\'\' AND (is_public = ' . db_param() . ' OR user_id = ' . db_param() . ') ORDER BY is_public DESC, name ASC'; $t_result = db_query($t_query, array($t_project_id, true, $t_user_id)); while ($t_row = db_fetch_array($t_result)) { $t_overall_query_arr[$t_row['id']] = $t_row['name']; } $t_overall_query_arr = array_unique($t_overall_query_arr); asort($t_overall_query_arr); return $t_overall_query_arr; }
/** * Collect valid email recipients for email notification * @todo yarick123: email_collect_recipients(...) will be completely rewritten to provide additional information such as language, user access,.. * @todo yarick123:sort recipients list by language to reduce switches between different languages * @param integer $p_bug_id A bug identifier. * @param string $p_notify_type Notification type. * @param array $p_extra_user_ids_to_email Array of additional email addresses to notify. * @return array */ function email_collect_recipients($p_bug_id, $p_notify_type, array $p_extra_user_ids_to_email = array()) { $t_recipients = array(); # add explicitly specified users $t_explicit_enabled = ON == email_notify_flag($p_notify_type, 'explicit'); foreach ($p_extra_user_ids_to_email as $t_user_id) { if ($t_explicit_enabled) { $t_recipients[$t_user_id] = true; log_event(LOG_EMAIL_RECIPIENT, 'Issue = #%d, add @U%d (explicitly specified)', $p_bug_id, $t_user_id); } else { log_event(LOG_EMAIL_RECIPIENT, 'Issue = #%d, skip @U%d (explicit disabled)', $p_bug_id, $t_user_id); } } # add Reporter $t_reporter_id = bug_get_field($p_bug_id, 'reporter_id'); if (ON == email_notify_flag($p_notify_type, 'reporter')) { $t_recipients[$t_reporter_id] = true; log_event(LOG_EMAIL_RECIPIENT, 'Issue = #%d, add @U%d (reporter)', $p_bug_id, $t_reporter_id); } else { log_event(LOG_EMAIL_RECIPIENT, 'Issue = #%d, skip @U%d (reporter disabled)', $p_bug_id, $t_reporter_id); } # add Handler $t_handler_id = bug_get_field($p_bug_id, 'handler_id'); if ($t_handler_id > 0) { if (ON == email_notify_flag($p_notify_type, 'handler')) { $t_recipients[$t_handler_id] = true; log_event(LOG_EMAIL_RECIPIENT, 'Issue = #%d, add @U%d (handler)', $p_bug_id, $t_handler_id); } else { log_event(LOG_EMAIL_RECIPIENT, 'Issue = #%d, skip @U%d (handler disabled)', $p_bug_id, $t_handler_id); } } $t_project_id = bug_get_field($p_bug_id, 'project_id'); # add users monitoring the bug $t_monitoring_enabled = ON == email_notify_flag($p_notify_type, 'monitor'); db_param_push(); $t_query = 'SELECT DISTINCT user_id FROM {bug_monitor} WHERE bug_id=' . db_param(); $t_result = db_query($t_query, array($p_bug_id)); while ($t_row = db_fetch_array($t_result)) { $t_user_id = $t_row['user_id']; if ($t_monitoring_enabled) { $t_recipients[$t_user_id] = true; log_event(LOG_EMAIL_RECIPIENT, 'Issue = #%d, add @U%d (monitoring)', $p_bug_id, $t_user_id); } else { log_event(LOG_EMAIL_RECIPIENT, 'Issue = #%d, skip @U%d (monitoring disabled)', $p_bug_id, $t_user_id); } } # add Category Owner if (ON == email_notify_flag($p_notify_type, 'category')) { $t_category_id = bug_get_field($p_bug_id, 'category_id'); if ($t_category_id > 0) { $t_category_assigned_to = category_get_field($t_category_id, 'user_id'); if ($t_category_assigned_to > 0) { $t_recipients[$t_category_assigned_to] = true; log_event(LOG_EMAIL_RECIPIENT, sprintf('Issue = #%d, add Category Owner = @U%d', $p_bug_id, $t_category_assigned_to)); } } } # add users who contributed bugnotes $t_bugnote_id = bugnote_get_latest_id($p_bug_id); $t_bugnote_date = bugnote_get_field($t_bugnote_id, 'last_modified'); $t_bug = bug_get($p_bug_id); $t_bug_date = $t_bug->last_updated; $t_notes_enabled = ON == email_notify_flag($p_notify_type, 'bugnotes'); db_param_push(); $t_query = 'SELECT DISTINCT reporter_id FROM {bugnote} WHERE bug_id = ' . db_param(); $t_result = db_query($t_query, array($p_bug_id)); while ($t_row = db_fetch_array($t_result)) { $t_user_id = $t_row['reporter_id']; if ($t_notes_enabled) { $t_recipients[$t_user_id] = true; log_event(LOG_EMAIL_RECIPIENT, 'Issue = #%d, add @U%d (note author)', $p_bug_id, $t_user_id); } else { log_event(LOG_EMAIL_RECIPIENT, 'Issue = #%d, skip @U%d (note author disabled)', $p_bug_id, $t_user_id); } } # add project users who meet the thresholds $t_bug_is_private = bug_get_field($p_bug_id, 'view_state') == VS_PRIVATE; $t_threshold_min = email_notify_flag($p_notify_type, 'threshold_min'); $t_threshold_max = email_notify_flag($p_notify_type, 'threshold_max'); $t_threshold_users = project_get_all_user_rows($t_project_id, $t_threshold_min); foreach ($t_threshold_users as $t_user) { if ($t_user['access_level'] <= $t_threshold_max) { if (!$t_bug_is_private || access_compare_level($t_user['access_level'], config_get('private_bug_threshold'))) { $t_recipients[$t_user['id']] = true; log_event(LOG_EMAIL_RECIPIENT, 'Issue = #%d, add @U%d (based on access level)', $p_bug_id, $t_user['id']); } } } # add users as specified by plugins $t_recipients_include_data = event_signal('EVENT_NOTIFY_USER_INCLUDE', array($p_bug_id, $p_notify_type)); foreach ($t_recipients_include_data as $t_plugin => $t_recipients_include_data2) { foreach ($t_recipients_include_data2 as $t_callback => $t_recipients_included) { # only handle if we get an array from the callback if (is_array($t_recipients_included)) { foreach ($t_recipients_included as $t_user_id) { $t_recipients[$t_user_id] = true; log_event(LOG_EMAIL_RECIPIENT, 'Issue = #%d, add @U%d (by %s plugin)', $p_bug_id, $t_user_id, $t_plugin); } } } } # FIXME: the value of $p_notify_type could at this stage be either a status # or a built-in actions such as 'owner and 'sponsor'. We have absolutely no # idea whether 'new' is indicating a new bug has been filed, or if the # status of an existing bug has been changed to 'new'. Therefore it is best # to just assume built-in actions have precedence over status changes. switch ($p_notify_type) { case 'new': case 'feedback': # This isn't really a built-in action (delete me!) # This isn't really a built-in action (delete me!) case 'reopened': case 'resolved': case 'closed': case 'bugnote': $t_pref_field = 'email_on_' . $p_notify_type; break; case 'owner': # The email_on_assigned notification type is now effectively # email_on_change_of_handler. $t_pref_field = 'email_on_assigned'; break; case 'deleted': case 'updated': case 'sponsor': case 'relation': case 'monitor': case 'priority': # This is never used, but exists in the database! # Issue #19459 these notification actions are not actually implemented # in the database and therefore aren't adjustable on a per-user # basis! The exception is 'monitor' that makes no sense being a # customisable per-user preference. # This is never used, but exists in the database! # Issue #19459 these notification actions are not actually implemented # in the database and therefore aren't adjustable on a per-user # basis! The exception is 'monitor' that makes no sense being a # customisable per-user preference. default: # Anything not built-in is probably going to be a status $t_pref_field = 'email_on_status'; break; } # @@@ we could optimize by modifiying user_cache() to take an array # of user ids so we could pull them all in. We'll see if it's necessary $t_final_recipients = array(); $t_user_ids = array_keys($t_recipients); user_cache_array_rows($t_user_ids); user_pref_cache_array_rows($t_user_ids); user_pref_cache_array_rows($t_user_ids, $t_bug->project_id); # Check whether users should receive the emails # and put email address to $t_recipients[user_id] foreach ($t_recipients as $t_id => $t_ignore) { # Possibly eliminate the current user if (auth_get_current_user_id() == $t_id && OFF == config_get('email_receive_own')) { log_event(LOG_EMAIL_RECIPIENT, 'Issue = #%d, drop @U%d (own action)', $p_bug_id, $t_id); continue; } # Eliminate users who don't exist anymore or who are disabled if (!user_exists($t_id) || !user_is_enabled($t_id)) { log_event(LOG_EMAIL_RECIPIENT, 'Issue = #%d, drop @U%d (user disabled)', $p_bug_id, $t_id); continue; } # Exclude users who have this notification type turned off if ($t_pref_field) { $t_notify = user_pref_get_pref($t_id, $t_pref_field); if (OFF == $t_notify) { log_event(LOG_EMAIL_RECIPIENT, 'Issue = #%d, drop @U%d (pref %s off)', $p_bug_id, $t_id, $t_pref_field); continue; } else { # Users can define the severity of an issue before they are emailed for # each type of notification $t_min_sev_pref_field = $t_pref_field . '_min_severity'; $t_min_sev_notify = user_pref_get_pref($t_id, $t_min_sev_pref_field); $t_bug_severity = bug_get_field($p_bug_id, 'severity'); if ($t_bug_severity < $t_min_sev_notify) { log_event(LOG_EMAIL_RECIPIENT, 'Issue = #%d, drop @U%d (pref threshold)', $p_bug_id, $t_id); continue; } } } # exclude users who don't have at least viewer access to the bug, # or who can't see bugnotes if the last update included a bugnote if (!access_has_bug_level(config_get('view_bug_threshold', null, $t_id, $t_bug->project_id), $p_bug_id, $t_id) || $t_bug_date == $t_bugnote_date && !access_has_bugnote_level(config_get('view_bug_threshold', null, $t_id, $t_bug->project_id), $t_bugnote_id, $t_id)) { log_event(LOG_EMAIL_RECIPIENT, 'Issue = #%d, drop @U%d (access level)', $p_bug_id, $t_id); continue; } # check to exclude users as specified by plugins $t_recipient_exclude_data = event_signal('EVENT_NOTIFY_USER_EXCLUDE', array($p_bug_id, $p_notify_type, $t_id)); $t_exclude = false; foreach ($t_recipient_exclude_data as $t_plugin => $t_recipient_exclude_data2) { foreach ($t_recipient_exclude_data2 as $t_callback => $t_recipient_excluded) { # exclude if any plugin returns true (excludes the user) if ($t_recipient_excluded) { $t_exclude = true; log_event(LOG_EMAIL_RECIPIENT, 'Issue = #%d, drop @U%d (by %s plugin)', $p_bug_id, $t_id, $t_plugin); } } } # user was excluded by a plugin if ($t_exclude) { continue; } # Finally, let's get their emails, if they've set one $t_email = user_get_email($t_id); if (is_blank($t_email)) { log_event(LOG_EMAIL_RECIPIENT, 'Issue = #%d, drop @U%d (no email address)', $p_bug_id, $t_id); } else { # @@@ we could check the emails for validity again but I think # it would be too slow $t_final_recipients[$t_id] = $t_email; } } return $t_final_recipients; }
/** * Schema update to migrate token data from php serialization to json. * This ensures it is not possible to execute code during un-serialization */ function install_check_token_serialization() { $query = 'SELECT * FROM {tokens} WHERE type=1 or type=2 or type=5'; $t_result = db_query($query); while ($t_row = db_fetch_array($t_result)) { $t_id = $t_row['id']; $t_value = $t_row['value']; if ($t_value === null) { $t_token = null; } else { $t_token = @unserialize($t_value); if ($t_token === false) { # If user hits a page other than install, tokens may be created using new code. $t_token = json_decode($t_value); if ($t_token !== null) { continue; } return 1; # Fatal: invalid data found in tokens table } } $t_json_token = json_encode($t_token); db_param_push(); $t_query = 'UPDATE {tokens} SET value=' . db_param() . ' WHERE id=' . db_param(); db_query($t_query, array($t_json_token, $t_id)); } # Return 2 because that's what ADOdb/DataDict does when things happen properly return 2; }
/** * Get the version_id, given the project_id and $p_version_id * returns false if not found, otherwise returns the id. * @param string $p_version A version string to look up. * @param integer $p_project_id A valid project identifier. * @param boolean $p_inherit True to include versions from parent projects, * false not to, or null to use configuration * setting ($g_subprojects_inherit_versions). * @return integer */ function version_get_id($p_version, $p_project_id = null, $p_inherit = null) { global $g_cache_versions; if ($p_project_id === null) { $c_project_id = helper_get_current_project(); } else { $c_project_id = (int) $p_project_id; } foreach ($g_cache_versions as $t_version) { if ($t_version['version'] === $p_version && $t_version['project_id'] == $c_project_id) { return $t_version['id']; } } db_param_push(); $t_project_where = version_get_project_where_clause($c_project_id, $p_inherit); $t_query = 'SELECT id FROM {project_version} WHERE ' . $t_project_where . ' AND version=' . db_param(); $t_result = db_query($t_query, array($p_version)); if ($t_row = db_result($t_result)) { return $t_row; } else { return false; } }
/** * updates the last_updated field * @param integer $p_sponsorship_id The sponsorship identifier to update. * @return boolean */ function sponsorship_update_date($p_sponsorship_id) { db_param_push(); $t_query = 'UPDATE {sponsorship} SET last_updated=' . db_param() . ' WHERE id=' . db_param(); db_query($t_query, array(db_now(), (int) $p_sponsorship_id)); sponsorship_clear_cache($p_sponsorship_id); return true; }
/** * delete all history associated with a bug * @param integer $p_bug_id A valid bug identifier. * @return void */ function history_delete($p_bug_id) { db_param_push(); $t_query = 'DELETE FROM {bug_history} WHERE bug_id=' . db_param(); db_query($t_query, array($p_bug_id)); }
/** * Delete all users from the project user list for a given project. This is * useful when deleting or closing a project. The $p_access_level_limit * parameter can be used to only remove users from a project if their access * level is below or equal to the limit. * @param integer $p_project_id A project identifier. * @param integer $p_access_level_limit Access level limit (null = no limit). * @return void */ function project_remove_all_users($p_project_id, $p_access_level_limit = null) { db_param_push(); $t_query = 'DELETE FROM {project_user_list} WHERE project_id = ' . db_param(); if ($p_access_level_limit !== null) { $t_query .= ' AND access_level <= ' . db_param(); db_query($t_query, array((int) $p_project_id, (int) $p_access_level_limit)); } else { db_query($t_query, array((int) $p_project_id)); } }
/** * Returns the default profile * @param integer $p_user_id A valid user identifier. * @return string */ function profile_get_default($p_user_id) { db_param_push(); $t_query = 'SELECT default_profile FROM {user_pref} WHERE user_id=' . db_param(); $t_result = db_query($t_query, array($p_user_id)); $t_default_profile = (int) db_result($t_result, 0, 0); return $t_default_profile; }
/** * print bug counts by reporter id * @return void */ function summary_print_by_reporter() { $t_reporter_summary_limit = config_get('reporter_summary_limit'); $t_project_id = helper_get_current_project(); $t_specific_where = helper_project_specific_where($t_project_id); if (' 1<>1' == $t_specific_where) { return; } $t_query = 'SELECT reporter_id, COUNT(*) as num FROM {bug} WHERE ' . $t_specific_where . ' GROUP BY reporter_id ORDER BY num DESC'; $t_result = db_query($t_query, array(), $t_reporter_summary_limit); $t_reporters = array(); while ($t_row = db_fetch_array($t_result)) { $t_reporters[] = $t_row['reporter_id']; } user_cache_array_rows($t_reporters); foreach ($t_reporters as $t_reporter) { $v_reporter_id = $t_reporter; db_param_push(); $t_query = 'SELECT COUNT(id) as bugcount, status FROM {bug} WHERE reporter_id=' . db_param() . ' AND ' . $t_specific_where . ' GROUP BY status ORDER BY status'; $t_result2 = db_query($t_query, array($v_reporter_id)); $t_bugs_open = 0; $t_bugs_resolved = 0; $t_bugs_closed = 0; $t_bugs_total = 0; $t_resolved_val = config_get('bug_resolved_status_threshold'); $t_closed_val = config_get('bug_closed_status_threshold'); while ($t_row2 = db_fetch_array($t_result2)) { $t_bugs_total += $t_row2['bugcount']; if ($t_closed_val <= $t_row2['status']) { $t_bugs_closed += $t_row2['bugcount']; } else { if ($t_resolved_val <= $t_row2['status']) { $t_bugs_resolved += $t_row2['bugcount']; } else { $t_bugs_open += $t_row2['bugcount']; } } } if (0 < $t_bugs_total) { $t_user = string_display_line(user_get_name($v_reporter_id)); $t_bug_link = '<a class="subtle" href="' . config_get('bug_count_hyperlink_prefix') . '&' . FILTER_PROPERTY_REPORTER_ID . '=' . $v_reporter_id; if (0 < $t_bugs_open) { $t_bugs_open = $t_bug_link . '&' . FILTER_PROPERTY_HIDE_STATUS . '=' . $t_resolved_val . '">' . $t_bugs_open . '</a>'; } if (0 < $t_bugs_resolved) { $t_bugs_resolved = $t_bug_link . '&' . FILTER_PROPERTY_STATUS . '=' . $t_resolved_val . '&' . FILTER_PROPERTY_HIDE_STATUS . '=' . $t_closed_val . '">' . $t_bugs_resolved . '</a>'; } if (0 < $t_bugs_closed) { $t_bugs_closed = $t_bug_link . '&' . FILTER_PROPERTY_STATUS . '=' . $t_closed_val . '&' . FILTER_PROPERTY_HIDE_STATUS . '=">' . $t_bugs_closed . '</a>'; } if (0 < $t_bugs_total) { $t_bugs_total = $t_bug_link . '&' . FILTER_PROPERTY_HIDE_STATUS . '=">' . $t_bugs_total . '</a>'; } summary_helper_print_row($t_user, $t_bugs_open, $t_bugs_resolved, $t_bugs_closed, $t_bugs_total); } } }
/** * retrieves and returns access matrix for a user from cache or caching if required. * @param integer $p_user_id Integer representing user identifier. * @return array returns an array of projects->accesslevel for the given user * @access private */ function access_cache_matrix_user($p_user_id) { global $g_cache_access_matrix, $g_cache_access_matrix_user_ids; if (!in_array((int) $p_user_id, $g_cache_access_matrix_user_ids)) { db_param_push(); $t_query = 'SELECT project_id, access_level FROM {project_user_list} WHERE user_id=' . db_param(); $t_result = db_query($t_query, array((int) $p_user_id)); # make sure we always have an array to return $g_cache_access_matrix[(int) $p_user_id] = array(); while ($t_row = db_fetch_array($t_result)) { $g_cache_access_matrix[(int) $p_user_id][(int) $t_row['project_id']] = (int) $t_row['access_level']; } $g_cache_access_matrix_user_ids[] = (int) $p_user_id; } return $g_cache_access_matrix[(int) $p_user_id]; }
/** * Retrieve a list of changes to a bug of the same type as the * given revision ID. * @param integer $p_rev_id A bug revision identifier. * @return array|null Array of Revision rows */ function bug_revision_like($p_rev_id) { db_param_push(); $t_query = 'SELECT bug_id, bugnote_id, type FROM {bug_revision} WHERE id=' . db_param(); $t_result = db_query($t_query, array($p_rev_id)); $t_row = db_fetch_array($t_result); if (!$t_row) { trigger_error(ERROR_BUG_REVISION_NOT_FOUND, ERROR); } $t_bug_id = $t_row['bug_id']; $t_bugnote_id = $t_row['bugnote_id']; $t_type = $t_row['type']; db_param_push(); $t_params = array($t_bug_id); $t_query = 'SELECT * FROM {bug_revision} WHERE bug_id=' . db_param(); if (REV_ANY < $t_type) { $t_query .= ' AND type=' . db_param(); $t_params[] = $t_type; } if ($t_bugnote_id > 0) { $t_query .= ' AND bugnote_id=' . db_param(); $t_params[] = $t_bugnote_id; } else { $t_query .= ' AND bugnote_id=0'; } $t_query .= ' ORDER BY id DESC'; $t_result = db_query($t_query, $t_params); $t_revisions = array(); while ($t_row = db_fetch_array($t_result)) { $t_revisions[$t_row['id']] = $t_row; } return $t_revisions; }
/** * Set the user's password to the given string, encoded as appropriate * * @param integer $p_user_id A valid user identifier. * @param string $p_password A password to set. * @param boolean $p_allow_protected Whether Allow password change to a protected account. This defaults to false. * @return boolean always true */ function user_set_password($p_user_id, $p_password, $p_allow_protected = false) { if (!$p_allow_protected) { user_ensure_unprotected($p_user_id); } # When the password is changed, invalidate the cookie to expire sessions that # may be active on all browsers. $c_cookie_string = auth_generate_unique_cookie_string(); # Delete token for password activation if there is any token_delete(TOKEN_ACCOUNT_ACTIVATION, $p_user_id); $c_password = auth_process_plain_password($p_password); db_param_push(); $t_query = 'UPDATE {user} SET password='******', cookie_string=' . db_param() . ' WHERE id=' . db_param(); db_query($t_query, array($c_password, $c_cookie_string, (int) $p_user_id)); return true; }
/** * Prints the preview of a text file attachment. * @param array $p_attachment An attachment array from within the array returned by the file_get_visible_attachments() function. * @return void */ function print_bug_attachment_preview_text(array $p_attachment) { if (!$p_attachment['exists']) { return; } echo "\n<pre class=\"bug-attachment-preview-text\">"; switch (config_get('file_upload_method')) { case DISK: if (file_exists($p_attachment['diskfile'])) { $t_content = file_get_contents($p_attachment['diskfile']); } break; case DATABASE: db_param_push(); $t_query = 'SELECT * FROM {bug_file} WHERE id=' . db_param(); $t_result = db_query($t_query, array((int) $p_attachment['id'])); $t_row = db_fetch_array($t_result); $t_content = $t_row['content']; break; default: trigger_error(ERROR_GENERIC, ERROR); } echo htmlspecialchars($t_content); echo '</pre>'; }
/** * Delete entry from email queue * @param integer $p_email_id Email queue identifier. * @return void */ function email_queue_delete($p_email_id) { db_param_push(); $t_query = 'DELETE FROM {email} WHERE email_id=' . db_param(); db_query($t_query, array($p_email_id)); log_event(LOG_EMAIL_VERBOSE, sprintf('message %d deleted from queue', $p_email_id)); }
/** * Copies all attachments from the source bug to the destination bug * * Does not perform history logging and does not perform access checks. * * @param integer $p_source_bug_id Source Bug. * @param integer $p_dest_bug_id Destination Bug. * @return void */ function file_copy_attachments($p_source_bug_id, $p_dest_bug_id) { db_param_push(); $t_query = 'SELECT * FROM {bug_file} WHERE bug_id = ' . db_param(); $t_result = db_query($t_query, array($p_source_bug_id)); $t_count = db_num_rows($t_result); $t_project_id = bug_get_field($p_source_bug_id, 'project_id'); for ($i = 0; $i < $t_count; $i++) { $t_bug_file = db_fetch_array($t_result); # prepare the new diskfile name and then copy the file $t_source_file = $t_bug_file['folder'] . $t_bug_file['diskfile']; if (config_get('file_upload_method') == DISK) { $t_source_file = file_normalize_attachment_path($t_source_file, $t_project_id); $t_file_path = dirname($t_source_file) . DIRECTORY_SEPARATOR; } else { $t_file_path = $t_bug_file['folder']; } $t_new_diskfile_name = file_generate_unique_name($t_file_path); $t_new_diskfile_location = $t_file_path . $t_new_diskfile_name; $t_new_file_name = file_get_display_name($t_bug_file['filename']); if (config_get('file_upload_method') == DISK) { # Skip copy operation if file does not exist (i.e. target bug will have missing attachment) # @todo maybe we should trigger an error instead in this case ? if (file_exists($t_source_file)) { copy($t_source_file, $t_new_diskfile_location); chmod($t_new_diskfile_location, config_get('attachments_file_permissions')); } } db_param_push(); $t_query = 'INSERT INTO {bug_file} ( bug_id, title, description, diskfile, filename, folder, filesize, file_type, date_added, user_id, content ) VALUES ( ' . db_param() . ', ' . db_param() . ', ' . db_param() . ', ' . db_param() . ', ' . db_param() . ', ' . db_param() . ', ' . db_param() . ', ' . db_param() . ', ' . db_param() . ', ' . db_param() . ', ' . db_param() . ')'; db_query($t_query, array($p_dest_bug_id, $t_bug_file['title'], $t_bug_file['description'], $t_new_diskfile_name, $t_new_file_name, $t_file_path, $t_bug_file['filesize'], $t_bug_file['file_type'], $t_bug_file['date_added'], $t_bug_file['user_id'], $t_bug_file['content'])); } }
/** * Gets a limited set of news rows to be viewed on one page based on the criteria * defined in the configuration file. * * @param integer $p_offset Offset. * @param integer $p_project_id A project identifier. * @return array */ function news_get_limited_rows($p_offset, $p_project_id = null) { if ($p_project_id === null) { $p_project_id = helper_get_current_project(); } $c_offset = (int) $p_offset; $t_projects = current_user_get_all_accessible_subprojects($p_project_id); $t_projects[] = (int) $p_project_id; if (ALL_PROJECTS != $p_project_id) { $t_projects[] = ALL_PROJECTS; } $t_news_view_limit = config_get('news_view_limit'); $t_news_view_limit_days = config_get('news_view_limit_days') * SECONDS_PER_DAY; switch (config_get('news_limit_method')) { case 0: db_param_push(); # BY_LIMIT - Select the news posts $t_query = 'SELECT * FROM {news}'; if (1 == count($t_projects)) { $c_project_id = $t_projects[0]; $t_query .= ' WHERE project_id=' . db_param(); $t_params = array($c_project_id); } else { $t_query .= ' WHERE project_id IN (' . join($t_projects, ',') . ')'; $t_params = null; } $t_query .= ' ORDER BY announcement DESC, id DESC'; $t_result = db_query($t_query, $t_params, $t_news_view_limit, $c_offset); break; case 1: db_param_push(); # BY_DATE - Select the news posts $t_query = 'SELECT * FROM {news} WHERE ( ' . db_helper_compare_time(db_param(), '<', 'date_posted', $t_news_view_limit_days) . ' OR announcement = ' . db_param() . ' ) '; $t_params = array(db_now(), 1); if (1 == count($t_projects)) { $c_project_id = $t_projects[0]; $t_query .= ' AND project_id=' . db_param(); $t_params[] = $c_project_id; } else { $t_query .= ' AND project_id IN (' . join($t_projects, ',') . ')'; } $t_query .= ' ORDER BY announcement DESC, id DESC'; $t_result = db_query($t_query, $t_params, $t_news_view_limit, $c_offset); break; } $t_rows = array(); while ($t_row = db_fetch_array($t_result)) { array_push($t_rows, $t_row); } return $t_rows; }
/** * Check category can be deleted * @param string $p_category_id Category identifier. * @return boolean Return true if the category valid for delete, otherwise false * @access public */ function category_can_delete($p_category_id) { db_param_push(); $t_query = 'SELECT COUNT(id) FROM {bug} WHERE category_id=' . db_param(); $t_bug_count = db_result(db_query($t_query, array($p_category_id))); return $t_bug_count == 0; }
/** * return an array of sub-project IDs of a certain project to which the user has access * @param integer $p_user_id A valid user identifier. * @param integer $p_project_id A valid project identifier. * @param boolean $p_show_disabled Include disabled projects in the resulting array. * @return array */ function user_get_accessible_subprojects($p_user_id, $p_project_id, $p_show_disabled = false) { global $g_user_accessible_subprojects_cache; if (null !== $g_user_accessible_subprojects_cache && auth_get_current_user_id() == $p_user_id && false == $p_show_disabled) { if (isset($g_user_accessible_subprojects_cache[$p_project_id])) { return $g_user_accessible_subprojects_cache[$p_project_id]; } else { return array(); } } db_param_push(); if (access_has_global_level(config_get('private_project_threshold'), $p_user_id)) { $t_enabled_clause = $p_show_disabled ? '' : 'p.enabled = ' . db_param() . ' AND'; $t_query = 'SELECT DISTINCT p.id, p.name, ph.parent_id FROM {project} p LEFT JOIN {project_hierarchy} ph ON ph.child_id = p.id WHERE ' . $t_enabled_clause . ' ph.parent_id IS NOT NULL ORDER BY p.name'; $t_result = db_query($t_query, $p_show_disabled ? array() : array(true)); } else { $t_query = 'SELECT DISTINCT p.id, p.name, ph.parent_id FROM {project} p LEFT JOIN {project_user_list} u ON p.id = u.project_id AND u.user_id=' . db_param() . ' LEFT JOIN {project_hierarchy} ph ON ph.child_id = p.id WHERE ' . ($p_show_disabled ? '' : 'p.enabled = ' . db_param() . ' AND ') . ' ph.parent_id IS NOT NULL AND ( p.view_state=' . db_param() . ' OR (p.view_state=' . db_param() . ' AND u.user_id=' . db_param() . ' ) ) ORDER BY p.name'; $t_param = array($p_user_id, VS_PUBLIC, VS_PRIVATE, $p_user_id); if (!$p_show_disabled) { # Insert enabled flag value in 2nd position of parameter array array_splice($t_param, 1, 0, true); } $t_result = db_query($t_query, $t_param); } $t_projects = array(); while ($t_row = db_fetch_array($t_result)) { if (!isset($t_projects[(int) $t_row['parent_id']])) { $t_projects[(int) $t_row['parent_id']] = array(); } array_push($t_projects[(int) $t_row['parent_id']], (int) $t_row['id']); } if (auth_get_current_user_id() == $p_user_id) { $g_user_accessible_subprojects_cache = $t_projects; } if (!isset($t_projects[(int) $p_project_id])) { $t_projects[(int) $p_project_id] = array(); } return $t_projects[(int) $p_project_id]; }
/** * check if there is a relationship between two bugs * return id if found 0 otherwise * @param integer $p_src_bug_id Source bug identifier. * @param integer $p_dest_bug_id Destination bug identifier. * @return integer Relationship ID */ function relationship_exists($p_src_bug_id, $p_dest_bug_id) { $c_src_bug_id = (int) $p_src_bug_id; $c_dest_bug_id = (int) $p_dest_bug_id; db_param_push(); $t_query = 'SELECT * FROM {bug_relationship} WHERE (source_bug_id=' . db_param() . ' AND destination_bug_id=' . db_param() . ') OR (source_bug_id=' . db_param() . ' AND destination_bug_id=' . db_param() . ')'; $t_result = db_query($t_query, array($c_src_bug_id, $c_dest_bug_id, $c_dest_bug_id, $c_src_bug_id), 1); if ($t_row = db_fetch_array($t_result)) { # return the first id return $t_row['id']; } else { # no relationship found return 0; } }