diff --git a/Source/Source.API.php b/Source/Source.API.php index 00bc399..7226f98 100644 --- a/Source/Source.API.php +++ b/Source/Source.API.php @@ -127,12 +127,24 @@ * @param object Changeset object */ function Source_Parse_Users( &$p_changeset ) { + static $s_vcs_names; static $s_names = array(); static $s_emails = array(); + # cache the vcs username mappings + if ( is_null( $s_vcs_names ) ) { + $s_vcs_names = SourceUser::load_mappings(); + } + # Handle the changeset author while ( !$p_changeset->user_id ) { + # Check username associations + if ( isset( $s_vcs_names[ $p_changeset->author ] ) ) { + $p_changeset->user_id = $s_vcs_names[ $p_changeset->author ]; + break; + } + # Look up the email address if given if ( $t_email = $p_changeset->author_email ) { if ( isset( $s_emails[ $t_email ] ) ) { @@ -168,6 +180,12 @@ # Handle the changeset committer while ( !$p_changeset->committer_id ) { + # Check username associations + if ( isset( $s_vcs_names[ $p_changeset->committer ] ) ) { + $p_changeset->user_id = $s_vcs_names[ $p_changeset->committer ]; + break; + } + # Look up the email address if given if ( $t_email = $t_email ) { if ( isset( $s_emails[ $t_email ] ) ) { @@ -1225,3 +1243,95 @@ } } +/** + * Object for handling VCS username associations. + */ +class SourceUser { + var $new = true; + + var $user_id; + var $username; + + function __construct( $p_user_id, $p_username='' ) { + $this->user_id = $p_user_id; + $this->username = $p_username; + } + + /** + * Load a user object from the database for a given user ID, or generate + * a new object if the database entry does not exist. + * @param int User ID + * @return object User object + */ + static function load( $p_user_id ) { + $t_user_table = plugin_table( 'user', 'Source' ); + + $t_query = "SELECT * FROM $t_user_table WHERE user_id=" . db_param(); + $t_result = db_query_bound( $t_query, array( $p_user_id ) ); + + if ( db_num_rows( $t_result ) > 0 ) { + $t_row = db_fetch_array( $t_result ); + + $t_user = new SourceUser( $t_row['user_id'], $t_row['username'] ); + $t_user->new = false; + + } else { + $t_user = new SourceUser( $p_user_id ); + } + + return $t_user; + } + + /** + * Load all user objects from the database and create an array indexed by + * username, pointing to user IDs. + * @return array Username mappings + */ + static function load_mappings() { + $t_user_table = plugin_table( 'user', 'Source' ); + + $t_query = "SELECT * FROM $t_user_table"; + $t_result = db_query( $t_query ); + + $t_usernames = array(); + while( $t_row = db_fetch_array( $t_result ) ) { + $t_usernames[ $t_row['username'] ] = $t_row['user_id']; + } + + return $t_usernames; + } + + /** + * Persist a user object to the database. If the user object contains a blank + * username, then delete any existing data from the database to minimize storage. + */ + function save() { + $t_user_table = plugin_table( 'user', 'Source' ); + + # handle new objects + if ( $this->new ) { + if ( is_blank( $this->username ) ) { # do nothing + return; + + } else { # insert new entry + $t_query = "INSERT INTO $t_user_table ( user_id, username ) VALUES (" . + db_param() . ', ' . db_param() . ')'; + db_query_bound( $t_query, array( $this->user_id, $this->username ) ); + + $this->new = false; + } + + # handle loaded objects + } else { + if ( is_blank( $this->username ) ) { # delete existing entry + $t_query = "DELETE FROM $t_user_table WHERE user_id=" . db_param(); + db_query_bound( $t_query, array( $this->user_id ) ); + + } else { # update existing entry + $t_query = "UPDATE $t_user_table SET username=" . db_param() . + ' WHERE user_id=' . db_param(); + db_query_bound( $t_query, array( $this->username, $this->user_id ) ); + } + } + } +} diff --git a/Source/Source.php b/Source/Source.php index bda242a..e96640d 100644 --- a/Source/Source.php +++ b/Source/Source.php @@ -190,6 +190,11 @@ version C(64) NOTNULL DEFAULT \" '' \", regex C(128) NOTNULL DEFAULT \" '' \" " ) ), + # 2009-04-15 - Allow a user/admin to specify a user's VCS username + array( 'CreateTableSQL', array( plugin_table( 'user' ), " + user_id I NOTNULL UNSIGNED PRIMARY, + username C(64) NOTNULL DEFAULT \" '' \" + " ) ), ); } diff --git a/Source/SourceIntegration.php b/Source/SourceIntegration.php index 871d929..573671f 100644 --- a/Source/SourceIntegration.php +++ b/Source/SourceIntegration.php @@ -21,7 +21,10 @@ return array( 'EVENT_VIEW_BUG_EXTRA' => 'display_bug', 'EVENT_DISPLAY_FORMATTED' => 'display_formatted', - 'EVENT_MENU_ISSUE' => 'display_changeset_link' + 'EVENT_MENU_ISSUE' => 'display_changeset_link', + + 'EVENT_ACCOUNT_PREF_UPDATE_FORM' => 'account_update_form', + 'EVENT_ACCOUNT_PREF_UPDATE' => 'account_update', ); } @@ -82,4 +85,39 @@ return $t_string; } + + /** + * When updating user preferences, allowing the user or admin to specify + * a version control username to be associated with the account. + * @param string Event name + * @param int User ID + */ + function account_update_form( $p_event, $p_user_id ) { + $t_user = SourceUser::load( $p_user_id ); + + echo '