View Issue Details

IDProjectCategoryView StatusLast Update
0011046mantisbtemailpublic2010-02-22 14:35
Reporterclaustre Assigned Tovboctor  
PriorityhighSeveritymajorReproducibilityalways
Status closedResolutionfixed 
Product Version1.2.0rc1 
Fixed in Version1.2.0 
Summary0011046: notification emails send to an unassigned user
Description

With our installation from the beginning we have strange behavior with
emails sent to people who are not assigned to a ticket. Checking monitoring
or account setting we didn't find any configuration which can explain such
a behaviour.
below an example of email message received by the user hwitsch from weeks
each time someone assigns a ticket:

The following issue has been ASSIGNED.
======================================================================
http://mantis/view.php?id=310
======================================================================
Reported By: petitdem
Assigned To: petitdem
======================================================================
Project: Beamline Support
Issue ID: 310
Category: ID11
Reproducibility: have not tried
Severity: minor
Priority: normal
Status: assigned
Assisted by: N/A
Deadline: 2009-09-26
Est. Time (hrs): 0
Requesting User:
Spent Time (hrs): 0
======================================================================
Date Submitted: 2009-09-03 16:48 CEST
Last Modified: 2009-10-15 10:31 CEST
======================================================================
Summary: Modify musst program
Description:
add a ttl trigger
======================================================================

Issue History
Date Modified Username Field Change
======================================================================
2009-09-03 16:48 petitdem New Issue
2009-09-03 16:48 petitdem Assisted by => N/A
2009-09-03 16:48 petitdem Deadline => 2009-09-26
2009-09-03 16:48 petitdem Est. Time (hrs) => 0
2009-09-03 16:48 petitdem Spent Time (hrs) => 0
2009-10-15 10:31 berruyer Assisted by N/A => N/A
2009-10-15 10:31 berruyer Assigned To => petitdem
2009-10-15 10:31 berruyer Status new => assigned

Tagspatch
Attached Files
Doc2.pdf (349,586 bytes)
user_pref_api.php (17,298 bytes)   
<?php
# MantisBT - a php based bugtracking system

# MantisBT is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
#
# MantisBT is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with MantisBT.  If not, see <http://www.gnu.org/licenses/>.

/**
 * User Preferences API
 * @copyright Copyright (C) 2000 - 2002  Kenzaburo Ito - kenito@300baud.org
 * @copyright Copyright (C) 2002 - 2009  MantisBT Team - mantisbt-dev@lists.sourceforge.net
 * @link http://www.mantisbt.org
 * @package CoreAPI
 * @subpackage UserPreferencesAPI
 */

/**
 * Preference Structure Definition
 * @package MantisBT
 * @subpackage classes
 */
class UserPreferences {
	protected $default_profile = NULL;
	protected $default_project = NULL;
	protected $advanced_report = NULL;
	protected $advanced_view = NULL;
	protected $advanced_update = NULL;
	protected $refresh_delay = NULL;
	protected $redirect_delay = NULL;
	protected $bugnote_order = NULL;
	protected $email_on_new = NULL;
	protected $email_on_assigned = NULL;
	protected $email_on_feedback = NULL;
	protected $email_on_resolved = NULL;
	protected $email_on_closed = NULL;
	protected $email_on_reopened = NULL;
	protected $email_on_bugnote = NULL;
	protected $email_on_status = NULL;
	protected $email_on_priority = NULL;
	protected $email_on_new_min_severity = NULL;
	protected $email_on_assigned_min_severity = NULL;
	protected $email_on_feedback_min_severity = NULL;
	protected $email_on_resolved_min_severity = NULL;
	protected $email_on_closed_min_severity = NULL;
	protected $email_on_reopened_min_severity = NULL;
	protected $email_on_bugnote_min_severity = NULL;
	protected $email_on_status_min_severity = NULL;
	protected $email_on_priority_min_severity = NULL;
	protected $email_bugnote_limit = NULL;
	protected $language = NULL;
	protected $timezone = NULL;

	private $pref_user_id;
	private $pref_project_id;

	private static $default_mapping = array(
	'default_profile' => 'default_profile',
	'default_project' => 'default_project',
	'advanced_report' => 'default_advanced_report',
	'advanced_view' => 'default_advanced_view',
	'advanced_update' => 'default_advanced_update',
	'refresh_delay' => 'default_refresh_delay',
	'redirect_delay' => 'default_redirect_delay',
	'bugnote_order' => 'default_bugnote_order',
	'email_on_new' => 'default_email_on_new',
	'email_on_assigned' => 'default_email_on_assigned',
	'email_on_feedback' => 'default_email_on_feedback',
	'email_on_resolved' => 'default_email_on_resolved',
	'email_on_closed' => 'default_email_on_closed',
	'email_on_reopened' => 'default_email_on_reopened',
	'email_on_bugnote' => 'default_email_on_bugnote',
	'email_on_status' => 'default_email_on_status',
	'email_on_priority' => 'default_email_on_priority',
	'email_on_new_min_severity' => 'default_email_on_new_minimum_severity',
	'email_on_assigned_min_severity' => 'default_email_on_assigned_minimum_severity',
	'email_on_feedback_min_severity' => 'default_email_on_feedback_minimum_severity',
	'email_on_resolved_min_severity' => 'default_email_on_resolved_minimum_severity',
	'email_on_closed_min_severity' => 'default_email_on_closed_minimum_severity',
	'email_on_reopened_min_severity' => 'default_email_on_reopened_minimum_severity',
	'email_on_bugnote_min_severity' => 'default_email_on_bugnote_minimum_severity',
	'email_on_status_min_severity' => 'default_email_on_status_minimum_severity',
	'email_on_priority_min_severity' => 'default_email_on_priority_minimum_severity',
	'email_bugnote_limit' => 'default_email_bugnote_limit',
	'language' => 'default_language',
	'timezone' => 'default_timezone',
	);
	
	/**
	 * Constructor
	 * @param int $p_user_id
	 * @param int $p_project_id
	 */
	function UserPreferences( $p_user_id, $p_project_id ) {
		$this->default_profile = 0;
		$this->default_project = ALL_PROJECTS;

		$this->pref_user_id = (int)$p_user_id;
		$this->pref_project_id = (int)$p_project_id;
	}

	/**
	 * @param string $name
	 * @param string $value
	 * @private
	 */
	public function __set($name, $value) {
		switch ($name) {
			case 'timezone':
				if( $value == '' ) {
					$value = null;
				}
		}
		$this->$name = $value;
	}

	/**
	 * @param string $t_string
	 * @private
	 */
	public function __get( $p_string ) {
		if( is_null( $this->$p_string ) ) {
			$this->$p_string = config_get( self::$default_mapping[$p_string], null, $this->pref_user_id, $this->pref_project_id );
		}
		return $this->$p_string;
	}

	/**
	 * @param string $t_string
	 */
	function Get( $p_string ) {
		if( is_null( $this->$p_string ) ) {
			$this->$p_string = config_get( self::$default_mapping[$p_string], null, $this->pref_user_id, $this->pref_project_id );
		}
		return $this->$p_string;
	}
}

# ########################################
# SECURITY NOTE: cache globals are initialized here to prevent them
#   being spoofed if register_globals is turned on

$g_cache_user_pref = array();
$g_cache_current_user_pref = array();

/**
 * Cache a user preferences row if necessary and return the cached copy
 *  If the third parameter is true (default), trigger an error
 *  if the preferences can't be found.  If the second parameter is
 *  false, return false if the preferences can't be found.
 *
 * @param int $p_user_id
 * @param int $p_project_id
 * @param bool $p_trigger_errors
 * @return false|array
 */
function user_pref_cache_row( $p_user_id, $p_project_id = ALL_PROJECTS, $p_trigger_errors = true ) {
	global $g_cache_user_pref;

	if( isset( $g_cache_user_pref[(int)$p_user_id][(int)$p_project_id] ) ) {
		return $g_cache_user_pref[(int)$p_user_id][(int)$p_project_id];
	}

	$t_user_pref_table = db_get_table( 'mantis_user_pref_table' );

	$query = "SELECT *
				  FROM $t_user_pref_table
				  WHERE user_id=" . db_param() . " AND project_id=" . db_param();
	$result = db_query_bound( $query, Array( (int)$p_user_id, (int)$p_project_id ) );

	if( 0 == db_num_rows( $result ) ) {
		if( $p_trigger_errors ) {
			trigger_error( ERROR_USER_PREFS_NOT_FOUND, ERROR );
		} else {
			$g_cache_user_pref[(int)$p_user_id][(int)$p_project_id] = false;
			return false;
		}
	}

	$row = db_fetch_array( $result );

	if( !isset( $g_cache_user_pref[(int)$p_user_id] ) ) {
		$g_cache_user_pref[(int)$p_user_id] = array();
	}

	$g_cache_user_pref[(int)$p_user_id][(int)$p_project_id] = $row;

	return $row;
}

/**
 * Cache user preferences for a set of users
 * @param array $p_user_id_array 
 * @param int $p_project_id
 * @return null
 */
function user_pref_cache_array_rows( $p_user_id_array, $p_project_id = ALL_PROJECTS ) {
	global $g_cache_user_pref;
	$c_user_id_array = array();

	foreach( $p_user_id_array as $t_user_id ) {
		if( !isset( $g_cache_user_pref[(int) $t_user_id][(int)$p_project_id] ) ) {
			$c_user_id_array[(int)$t_user_id] = (int)$t_user_id;
		}
	}

	if( empty( $c_user_id_array ) ) {
		return;
	}

	$t_user_pref_table = db_get_table( 'mantis_user_pref_table' );

	$query = "SELECT *
				  FROM $t_user_pref_table
				  WHERE user_id IN (" . implode( ',', $c_user_id_array ) . ') AND project_id=' . db_param();

	$result = db_query_bound( $query, Array( (int)$p_project_id ) );
    
	while( $row = db_fetch_array( $result ) ) {
		if( !isset( $g_cache_user_pref[(int) $row['user_id']] ) ) {
			$g_cache_user_pref[(int) $row['user_id']] = array();
		}
		$g_cache_user_pref[(int) $row['user_id']][(int)$p_project_id] = $row;
		unset( $c_user_id_array[(int) $row['user_id']] );
	}

	foreach( $c_user_id_array as $t_user_id ) {
		$g_cache_user_pref[(int) $t_user_id][(int)$p_project_id] = false;
	}
	return;
}

/** 
 * Clear the user preferences cache (or just the given id if specified)
 * @param $p_user_id
 * @param $p_project_id
 * @return true
 */
function user_pref_clear_cache( $p_user_id = null, $p_project_id = null ) {
	global $g_cache_user_pref;

	if( null === $p_user_id ) {
		$g_cache_user_pref = array();
	} else if( null === $p_project_id ) {
		unset( $g_cache_user_pref[(int)$p_user_id] );
	} else {
		unset( $g_cache_user_pref[(int)$p_user_id][(int)$p_project_id] );
	}

	return true;
}

/**
 * return true if the user has prefs assigned for the given project,
 *  false otherwise
 * @param int $p_user_id
 * @param int $p_project_id
 * @return bool
 */
function user_pref_exists( $p_user_id, $p_project_id = ALL_PROJECTS ) {
	if( false === user_pref_cache_row( $p_user_id, $p_project_id, false ) ) {
		return false;
	} else {
		return true;
	}
}

/**
 * perform an insert of a preference object into the DB
 * @param int $p_user_id
 * @param int $p_project_id
 * @param UserPreferences $p_prefs
 * @return true
 */
function user_pref_insert( $p_user_id, $p_project_id, $p_prefs ) {
	static $t_vars;
	$c_user_id = db_prepare_int( $p_user_id );
	$c_project_id = db_prepare_int( $p_project_id );

	user_ensure_unprotected( $p_user_id );

	$t_user_pref_table = db_get_table( 'mantis_user_pref_table' );

	if ($t_vars == null ) {
		$t_vars = getClassProperties( 'UserPreferences', 'protected');
	}

	$t_values = array();

	$t_params[] = db_param(); // user_id
	$t_values[] = $c_user_id;
	$t_params[] = db_param(); // project_id
	$t_values[] = $c_project_id;
	foreach( $t_vars as $var => $val ) {
		array_push( $t_params, db_param());
		array_push( $t_values, $p_prefs->Get( $var ) );
	}

	$t_vars_string = implode( ', ', array_keys( $t_vars ) );
	$t_params_string = implode( ',', $t_params );

	$query = 'INSERT INTO ' . $t_user_pref_table .
			 ' (user_id, project_id, ' . $t_vars_string . ') ' .
			 ' VALUES ( ' . $t_params_string . ')';
	db_query_bound( $query, $t_values  );

	# db_query errors on failure so:
	return true;
}

/**
 * perform an update of a preference object into the DB
 * @param int $p_user_id
 * @param int $p_project_id
 * @param UserPreferences $p_prefs
 * @return true
 */
function user_pref_update( $p_user_id, $p_project_id, $p_prefs ) {
	static $t_vars;
	$c_user_id = db_prepare_int( $p_user_id );
	$c_project_id = db_prepare_int( $p_project_id );

	user_ensure_unprotected( $p_user_id );

	$t_user_pref_table = db_get_table( 'mantis_user_pref_table' );

	if ($t_vars == null ) {
		$t_vars = getClassProperties( 'UserPreferences', 'protected');
	}

	$t_pairs = array();
	$t_values = array();

	foreach( $t_vars as $var => $val ) {
		array_push( $t_pairs, "$var = " . db_param() ) ;
		array_push( $t_values, $p_prefs->$var );
	}

	$t_pairs_string = implode( ', ', $t_pairs );
	$t_values[] = $c_user_id;
	$t_values[] = $c_project_id;

	$query = "UPDATE $t_user_pref_table
				  SET $t_pairs_string
				  WHERE user_id=" . db_param() . " AND project_id=" . db_param();
	db_query_bound( $query, $t_values );

	user_pref_clear_cache( $p_user_id, $p_project_id );

	# db_query errors on failure so:
	return true;
}

/**
 * delete a preferencess row
 * returns true if the prefs were successfully deleted
 * @param int $p_user_id
 * @param int $p_project_id
 * @return true
 */
function user_pref_delete( $p_user_id, $p_project_id = ALL_PROJECTS ) {
	$c_user_id = db_prepare_int( $p_user_id );
	$c_project_id = db_prepare_int( $p_project_id );

	user_ensure_unprotected( $p_user_id );

	$t_user_pref_table = db_get_table( 'mantis_user_pref_table' );

	$query = "DELETE FROM $t_user_pref_table
				  WHERE user_id=" . db_param() . " AND
				  		project_id=" . db_param();
	db_query_bound( $query, Array( $c_user_id, $c_project_id ) );

	user_pref_clear_cache( $p_user_id, $p_project_id );

	# db_query errors on failure so:
	return true;
}

/**
 * delete all preferences for a user in all projects
 * returns true if the prefs were successfully deleted
 *
 * It is far more efficient to delete them all in one query than to
 *  call user_pref_delete() for each one and the code is short so that's
 *  what we do
 * @param int $p_user_id
 * @return true
 */
function user_pref_delete_all( $p_user_id ) {
	$c_user_id = db_prepare_int( $p_user_id );

	user_ensure_unprotected( $p_user_id );

	$t_user_pref_table = db_get_table( 'mantis_user_pref_table' );

	$query = 'DELETE FROM ' . $t_user_pref_table . ' WHERE user_id=' . db_param();
	db_query_bound( $query, Array( $c_user_id ) );

	user_pref_clear_cache( $p_user_id );

	# db_query errors on failure so:
	return true;
}

/**
 * delete all preferences for a project for all users (part of deleting the project)
 * returns true if the prefs were successfully deleted
 *
 * It is far more efficient to delete them all in one query than to
 *  call user_pref_delete() for each one and the code is short so that's
 *  what we do
 * @param $p_project_id
 * @return true
 */
function user_pref_delete_project( $p_project_id ) {
	$c_project_id = db_prepare_int( $p_project_id );

	$t_user_pref_table = db_get_table( 'mantis_user_pref_table' );

	$query = 'DELETE FROM ' . $t_user_pref_table . ' WHERE project_id=' . db_param();
	db_query_bound( $query, Array( $c_project_id ) );

	# db_query errors on failure so:
	return true;
}

/**
 * return the user's preferences in a UserPreferences object
 * @param int $p_user_id
 * @param int $p_project_id
 * @return UserPreferences
 */
function user_pref_get( $p_user_id, $p_project_id = ALL_PROJECTS ) {
	static $t_vars;
	global $g_cache_current_user_pref;

	if ( isset( $g_cache_current_user_pref[(int)$p_project_id] ) &&  auth_get_current_user_id() == $p_user_id ) {
		return $g_cache_current_user_pref[(int)$p_project_id];
	}

	$t_prefs = new UserPreferences( $p_user_id, $p_project_id );

	$row = user_pref_cache_row( $p_user_id, $p_project_id, false );

	# If the user has no preferences for the given project
	if( false === $row ) {
		if( ALL_PROJECTS != $p_project_id ) {
			# Try to get the prefs for ALL_PROJECTS (the defaults)
			$row = user_pref_cache_row( $p_user_id, ALL_PROJECTS, false );
		}

		# If $row is still false (the user doesn't have default preferences)
		if( false === $row ) {
			# We use an empty array
			$row = array();
		}
	}

	if ($t_vars == null ) {
		$t_vars = getClassProperties( 'UserPreferences', 'protected');
	}

	$t_row_keys = array_keys( $row );

	# Check each variable in the class
	foreach( $t_vars as $var => $val ) {
		# If we got a field from the DB with the same name
		if( in_array( $var, $t_row_keys, true ) ) {
			# Store that value in the object
			$t_prefs->$var = $row[$var];
		}
	}
	if ( auth_get_current_user_id() == $p_user_id ) {
		$g_cache_current_user_pref[ (int)$p_project_id ] = $t_prefs;
	}
	return $t_prefs;
}

/**
 * Return the specified preference field for the user id
 * If the preference can't be found try to return a defined default
 * If that fails, trigger a WARNING and return ''
 * @param int $p_user_id
 * @param string $p_pref_name
 * @param int $p_project_id
 * @return string
 */
function user_pref_get_pref( $p_user_id, $p_pref_name, $p_project_id = ALL_PROJECTS ) {
	static $t_vars;

	$t_prefs = user_pref_get( $p_user_id, $p_project_id );

	if ($t_vars == null ) {
		$t_reflection = new ReflectionClass('UserPreferences');
		$t_vars = $t_reflection->getDefaultProperties();
	}

	if( in_array( $p_pref_name, array_keys( $t_vars ), true ) ) {
		return $t_prefs->Get( $p_pref_name );
	} else {
		error_parameters( $p_pref_name );
		trigger_error( ERROR_DB_FIELD_NOT_FOUND, WARNING );
		return '';
	}
}

/**
 * returns user language
 * @param int $p_user_id
 * @param int $p_project_id
 * @return string
 */
function user_pref_get_language( $p_user_id, $p_project_id = ALL_PROJECTS ) {
	$t_prefs = user_pref_get( $p_user_id, $p_project_id );

	// ensure the language is a valid one
	$t_lang = $t_prefs->language;
	if( !lang_language_exists( $t_lang ) ) {
		$t_lang = false;
	}
	return $t_lang;
}

/**
 * Set a user preference
 *
 * By getting the prefs for the project first we deal fairly well with defaults.
 *  If there are currently no prefs for that project, the ALL_PROJECTS prefs will
 *  be returned so we end up storing a new set of prefs for the given project
 *  based on the prefs for ALL_PROJECTS.  If there isn't even an entry for
 *  ALL_PROJECTS, we'd get returned a default UserPreferences object to modify.
 * @param int $p_user_id
 * @param string $p_pref_name
 * @param string $p_pref_value
 * @param int $p_project_id
 * @return true
 */
function user_pref_set_pref( $p_user_id, $p_pref_name, $p_pref_value, $p_project_id = ALL_PROJECTS ) {
	$t_prefs = user_pref_get( $p_user_id, $p_project_id );

	$t_prefs->$p_pref_name = $p_pref_value;

	user_pref_set( $p_user_id, $t_prefs, $p_project_id );

	return true;
}

/**
 * set the user's preferences for the project from the given preferences object
 * Do the work by calling user_pref_update() or user_pref_insert() as appropriate
 * @param int $p_user_id
 * @param UserPreferences $p_prefs
 * @param int $p_project_id
 * @return true
 */
function user_pref_set( $p_user_id, $p_prefs, $p_project_id = ALL_PROJECTS ) {
	if( user_pref_exists( $p_user_id, $p_project_id ) ) {
		return user_pref_update( $p_user_id, $p_project_id, $p_prefs );
	} else {
		return user_pref_insert( $p_user_id, $p_project_id, $p_prefs );
	}
}

user_pref_api.php (17,298 bytes)   

Activities

vboctor

vboctor

2009-10-17 12:40

manager   ~0023225

Please provide a dump of the configuration options that have "notify_flags" in their name.

claustre

claustre

2009-10-21 03:49

reporter   ~0023258

I do not know how to dump the config you request for, I've just uploaded
a screen dump of the E-mail Notification page.
Regards.

claustre

claustre

2009-10-21 03:54

reporter   ~0023260

OK looking into the table 'mantis_config_table', these are the dumps:

default_notify_flags =
a:6:{s:8:"reporter";i:1;s:7:"handler";i:1;s:7:"monitor";i:1;s:8:"bugnotes";i:1;s:13:"threshold_min";i:100;s:13:"threshold_max";i:0;}

notify_flags =
a:1:{s:8:"assigned";a:2:{s:13:"threshold_min";s:2:"10";s:13:"threshold_max";s:2:"55";}}

vboctor

vboctor

2009-10-21 03:56

manager   ~0023261

You should enable logging to understand the cause of such emails:

<pre>
/**

  • --- system logging ---
  • This controls the logging of information to a separate file for debug or audit
  • $g_log_level controls what information is logged
  • see constant_inc.php for details on the log channels available
  • e.g., $g_log_level = LOG_EMAIL | LOG_EMAIL_RECIPIENT | LOG_FILTERING | LOG_AJAX;
  • $g_log_destination specifies the file where the data goes
  • right now, only "file:<file path>" is supported
  • e.g. (Linux), $g_log_destination = 'file:/tmp/mantisbt.log';
  • e.g. (Windows), $g_log_destination = 'file:c:/temp/mantisbt.log';
  • see http://www.php.net/error_log for details
  • @global int $g_log_level
    */

$g_log_level = LOG_EMAIL | LOG_EMAIL_RECIPIENT;
$g_log_destination = 'file:/tmp/mantisbt.log';
</pre>

Once you do these settings, trigger the sending of such emails and then check the log file for details about the reason why the recipient was added.

vboctor

vboctor

2009-10-22 00:07

manager   ~0023276

The threshold min / max specify a range of access level to be notified on the event. All users of the project with an access level in this range will be notified even if they didn't participate in the specific bug.

claustre

claustre

2009-10-22 03:02

reporter   ~0023278

in our case the user hwitsch is not participating to the projects for which
he received email notification. I've activated the logging of notification
and give you here an example of what have been logged:
The ticket 761 is attached to the project 17 which has no user attached.
We only have users with 'developer' or 'manager' access level, is that can be a pb?
Regards,
Laurent

2009-10-21 13:33 CEST mail_recipient Issue = 0000761, add Reporter = @U4
2009-10-21 13:33 CEST mail_recipient Issue = 0000761, drop @U4 (own)
2009-10-21 13:34 CEST mail_recipient Issue = 0000761, add Reporter = @U4
2009-10-21 13:34 CEST mail_recipient Issue = 0000761, add Handler = @U4
2009-10-21 13:34 CEST mail_recipient Issue = 0000761, add Project User = @U6
2009-10-21 13:34 CEST mail_recipient Issue = 0000761, add Project User = @U7
2009-10-21 13:34 CEST mail_recipient Issue = 0000761, add Project User = @U8
2009-10-21 13:34 CEST mail_recipient Issue = 0000761, add Project User = @U9
2009-10-21 13:34 CEST mail_recipient Issue = 0000761, add Project User = @U10
2009-10-21 13:34 CEST mail_recipient Issue = 0000761, add Project User = @U12
2009-10-21 13:34 CEST mail_recipient Issue = 0000761, add Project User = @U13
2009-10-21 13:34 CEST mail_recipient Issue = 0000761, add Project User = @U14
2009-10-21 13:34 CEST mail_recipient Issue = 0000761, add Project User = @U15
2009-10-21 13:34 CEST mail_recipient Issue = 0000761, add Project User = @U18
2009-10-21 13:34 CEST mail_recipient Issue = 0000761, add Project User = @U20
2009-10-21 13:34 CEST mail_recipient Issue = 0000761, add Project User = @U19
2009-10-21 13:34 CEST mail_recipient Issue = 0000761, add Project User = @U21
2009-10-21 13:34 CEST mail_recipient Issue = 0000761, add Project User = @U22
2009-10-21 13:34 CEST mail_recipient Issue = 0000761, add Project User = @U23
2009-10-21 13:34 CEST mail_recipient Issue = 0000761, add Project User = @U24
2009-10-21 13:34 CEST mail_recipient Issue = 0000761, add Project User = @U25
2009-10-21 13:34 CEST mail_recipient Issue = 0000761, add Project User = @U26
2009-10-21 13:34 CEST mail_recipient Issue = 0000761, add Project User = @U27
2009-10-21 13:34 CEST mail_recipient Issue = 0000761, add Project User = @U28
2009-10-21 13:34 CEST mail_recipient Issue = 0000761, add Project User = @U29
2009-10-21 13:34 CEST mail_recipient Issue = 0000761, add Project User = @U30
2009-10-21 13:34 CEST mail_recipient Issue = 0000761, add Project User = @U45
2009-10-21 13:34 CEST mail_recipient Issue = 0000761, add Project User = @U32
2009-10-21 13:34 CEST mail_recipient Issue = 0000761, add Project User = @U33
2009-10-21 13:34 CEST mail_recipient Issue = 0000761, add Project User = @U34
2009-10-21 13:34 CEST mail_recipient Issue = 0000761, add Project User = @U35
2009-10-21 13:34 CEST mail_recipient Issue = 0000761, add Project User = @U37
2009-10-21 13:34 CEST mail_recipient Issue = 0000761, add Project User = @U46
2009-10-21 13:34 CEST mail_recipient Issue = 0000761, add Project User = @U41
2009-10-21 13:34 CEST mail_recipient Issue = 0000761, add Project User = @U42
2009-10-21 13:34 CEST mail_recipient Issue = 0000761, add Project User = @U43
2009-10-21 13:34 CEST mail_recipient Issue = 0000761, add Project User = @U44
2009-10-21 13:34 CEST mail_recipient Issue = 0000761, add Project User = @U47
2009-10-21 13:34 CEST mail_recipient Issue = 0000761, add Project User = @U48
2009-10-21 13:34 CEST mail_recipient Issue = 0000761, add Project User = @U51
2009-10-21 13:34 CEST mail_recipient Issue = 0000761, add Project User = @U52
2009-10-21 13:34 CEST mail_recipient Issue = 0000761, add Project User = @U57
2009-10-21 13:34 CEST mail_recipient Issue = 0000761, add Project User = @U58
2009-10-21 13:34 CEST mail_recipient Issue = 0000761, add Project User = @U59
2009-10-21 13:34 CEST mail_recipient Issue = 0000761, add Project User = @U60
2009-10-21 13:34 CEST mail_recipient Issue = 0000761, drop @U4 (own)
2009-10-21 13:34 CEST mail_recipient Issue = 0000761, drop @U6 (pref email_on_status off)
2009-10-21 13:34 CEST mail_recipient Issue = 0000761, drop @U7 (pref email_on_status off)
2009-10-21 13:34 CEST mail_recipient Issue = 0000761, drop @U8 (pref email_on_status off)
2009-10-21 13:34 CEST mail_recipient Issue = 0000761, drop @U9 (pref email_on_status off)
2009-10-21 13:34 CEST mail_recipient Issue = 0000761, drop @U10 (pref email_on_status off)
2009-10-21 13:34 CEST mail_recipient Issue = 0000761, drop @U12 (pref email_on_status off)
2009-10-21 13:34 CEST mail_recipient Issue = 0000761, drop @U13 (pref email_on_status off)
2009-10-21 13:34 CEST mail_recipient Issue = 0000761, drop @U14 (pref email_on_status off)
2009-10-21 13:34 CEST mail_recipient Issue = 0000761, drop @U15 (pref email_on_status off)
2009-10-21 13:34 CEST mail_recipient Issue = 0000761, drop @U18 (pref email_on_status off)
2009-10-21 13:34 CEST mail_recipient Issue = 0000761, drop @U20 (pref email_on_status off)
2009-10-21 13:34 CEST mail_recipient Issue = 0000761, drop @U19 (pref email_on_status off)
2009-10-21 13:34 CEST mail_recipient Issue = 0000761, drop @U21 (pref email_on_status off)
2009-10-21 13:34 CEST mail_recipient Issue = 0000761, drop @U22 (pref email_on_status off)
2009-10-21 13:34 CEST mail_recipient Issue = 0000761, drop @U23 (pref email_on_status off)
2009-10-21 13:34 CEST mail_recipient Issue = 0000761, drop @U24 (pref email_on_status off)
2009-10-21 13:34 CEST mail_recipient Issue = 0000761, drop @U25 (pref email_on_status off)
2009-10-21 13:34 CEST mail_recipient Issue = 0000761, drop @U26 (pref email_on_status off)
2009-10-21 13:34 CEST mail_recipient Issue = 0000761, drop @U27 (pref email_on_status off)
2009-10-21 13:34 CEST mail_recipient Issue = 0000761, drop @U28 (pref email_on_status off)
2009-10-21 13:34 CEST mail_recipient Issue = 0000761, drop @U29 (pref email_on_status off)
2009-10-21 13:34 CEST mail_recipient Issue = 0000761, drop @U45 (pref email_on_status off)
2009-10-21 13:34 CEST mail_recipient Issue = 0000761, drop @U32 (pref email_on_status off)
2009-10-21 13:34 CEST mail_recipient Issue = 0000761, drop @U33 (pref email_on_status off)
2009-10-21 13:34 CEST mail_recipient Issue = 0000761, drop @U34 (pref threshold)
2009-10-21 13:34 CEST mail_recipient Issue = 0000761, drop @U35 (pref email_on_status off)
2009-10-21 13:34 CEST mail_recipient Issue = 0000761, drop @U37 (pref email_on_status off)
2009-10-21 13:34 CEST mail_recipient Issue = 0000761, drop @U46 (pref email_on_status off)
2009-10-21 13:34 CEST mail_recipient Issue = 0000761, drop @U41 (pref email_on_status off)
2009-10-21 13:34 CEST mail_recipient Issue = 0000761, drop @U42 (pref email_on_status off)
2009-10-21 13:34 CEST mail_recipient Issue = 0000761, drop @U43 (pref email_on_status off)
2009-10-21 13:34 CEST mail_recipient Issue = 0000761, drop @U44 (pref email_on_status off)
2009-10-21 13:34 CEST mail_recipient Issue = 0000761, drop @U47 (pref email_on_status off)
2009-10-21 13:34 CEST mail_recipient Issue = 0000761, drop @U48 (pref email_on_status off)
2009-10-21 13:34 CEST mail_recipient Issue = 0000761, drop @U51 (pref email_on_status off)
2009-10-21 13:34 CEST mail_recipient Issue = 0000761, drop @U52 (pref email_on_status off)
2009-10-21 13:34 CEST mail_recipient Issue = 0000761, drop @U57 (pref email_on_status off)
2009-10-21 13:34 CEST mail_recipient Issue = 0000761, drop @U58 (pref email_on_status off)
2009-10-21 13:34 CEST mail_recipient Issue = 0000761, drop @U59 (pref email_on_status off)
2009-10-21 13:34 CEST mail_recipient Issue = 0000761, drop @U60 (pref email_on_status off)
2009-10-21 13:34 CEST mail Issue = 0000761, Type = assigned, Msg = 'email_notification_title_for_status_bug_assigned', User = @U30, Email = 'hwitsch@esrf.fr'.

vboctor

vboctor

2009-10-24 01:14

manager   ~0023307

Is your project public? If so, then all users are implicitly project users with the same access level they have globally. To fix this problem, you will have to change your project to private, and then explicitly add the users who you want to have access to the project and assign them the appropriate access level which can be different from their global access level.

claustre

claustre

2009-10-24 05:11

reporter   ~0023308

because we are a team of developers (36 people) all the projects have to be
public. Our pb is not that one, but how you can see on the bottom of the log output only the user hwitsch is notifying about the status change but he is not
handler neither monitor of the ticket. We removed the email address from his profile but he's still receiving messages.

vboctor

vboctor

2009-10-26 02:54

manager   ~0023321

  • Does this user has in his preference email on status notification off?
  • Is his email address still showing up in the logs after you have removed it from his user information? This would be really weird.
claustre

claustre

2009-10-28 05:36

reporter   ~0023439

yes, email on status notification preference is off,
yes, his address is still showing up.
It seems the dbase is corrupted concerning the email notifications ans we don't know how to clean up the dbase without risking some damages.
Any help?
Regards

vboctor

vboctor

2009-10-28 12:16

manager   ~0023443

Looks like you need someone to investigate your instance. If you are interested in paid services, please contact us via the website contact us page.

claustre

claustre

2009-11-06 04:39

reporter   ~0023608

Hi Victor,
just more info, I've just understood that the bug is reproducible when
one use the "Edit" page to update a new issue and to attached someone to the issue. In that case in the history one can see that first the filed "Attached to" is updated THEN the "Status" field moved from new to assigned.
In that case issue handle never received a email but hwitsch yes.
Now if one use the "Assigned to" button, everything work fine, but the history
of issue shows the reverse than in the use of the "Edit" button, first the field
"Status" is updated THEN the "Attached to" Field.
Maybe this could help you, before intervening in our system.
Regards,
Laurent

claustre

claustre

2009-11-17 09:30

reporter   ~0023739

Hi Victor,
I finally find a bug in user_pref_api.php where user_pref_cache_array_rows()
queried the mantis_user_pref_table with the "id" field instead of the "user_id".
I've just uploaded the patched file, the diff only concerned few lines:

223c223
< WHERE user_id IN (" . implode( ',', $c_user_id_array ) . ') AND project_id=' . db_param();

                            WHERE id IN (&quot; . implode( ',', $c_user_id_array ) . ') AND project_id=' . db_param();

226c226
<

228,229c228,229
< if( !isset( $g_cache_user_pref[(int) $row['user_id']] ) ) {
< $g_cache_user_pref[(int) $row['user_id']] = array();

          if( !isset( $g_cache_user_pref[(int) $row['id']] ) ) {
                  $g_cache_user_pref[(int) $row['id']] = array();

231,232c231,232
< $g_cache_user_pref[(int) $row['user_id']][(int)$p_project_id] = $row;
< unset( $c_user_id_array[(int) $row['user_id']] );

          $g_cache_user_pref[(int) $row['id']][(int)$p_project_id] = $row;
          unset( $c_user_id_array[(int) $row['id']] );

Could you confirm this is the bug?
Regards,
Laurent

vboctor

vboctor

2009-12-16 04:31

manager   ~0023912

I've applied the fix. However, what I don't understand is how this issue would be a user that is not related to an issue to receive an email. I can understand if flags like "email on new" can be randomly not honored because we pick flags from a different user.

Related Changesets

MantisBT: master-1.2.x 6ff6210c

2009-12-16 04:29

vboctor


Details Diff
Fixes 0011046: notification emails send to an unassigned user. Affected Issues
0011046
mod - core/user_pref_api.php Diff File

MantisBT: master 77a0fb65

2009-12-16 04:29

vboctor


Details Diff
Fixes 0011046: notification emails send to an unassigned user. Affected Issues
0011046
mod - core/user_pref_api.php Diff File