diff options
Diffstat (limited to 'Bugzilla/User.pm')
-rw-r--r-- | Bugzilla/User.pm | 148 |
1 files changed, 131 insertions, 17 deletions
diff --git a/Bugzilla/User.pm b/Bugzilla/User.pm index 0bc49d9b1..1c6e68078 100644 --- a/Bugzilla/User.pm +++ b/Bugzilla/User.pm @@ -50,6 +50,7 @@ use Bugzilla::Product; use Bugzilla::Classification; use Bugzilla::Field; use Bugzilla::Group; +use Bugzilla::Hook; use DateTime::TimeZone; use List::Util qw(max); @@ -91,16 +92,21 @@ use constant DB_TABLE => 'profiles'; # that you passed in for "name" to new(). That's because historically # Bugzilla::User used "name" for the realname field. This should be # fixed one day. -use constant DB_COLUMNS => ( - 'profiles.userid', - 'profiles.login_name', - 'profiles.realname', - 'profiles.mybugslink AS showmybugslink', - 'profiles.disabledtext', - 'profiles.disable_mail', - 'profiles.extern_id', - 'profiles.is_enabled', -); +sub DB_COLUMNS { + my $dbh = Bugzilla->dbh; + return ( + 'profiles.userid', + 'profiles.login_name', + 'profiles.realname', + 'profiles.mybugslink AS showmybugslink', + 'profiles.disabledtext', + 'profiles.disable_mail', + 'profiles.extern_id', + 'profiles.is_enabled', + $dbh->sql_date_format('last_seen_date', '%Y-%m-%d') . ' AS last_seen_date', + ), +} + use constant NAME_FIELD => 'login_name'; use constant ID_FIELD => 'userid'; use constant LIST_ORDER => NAME_FIELD; @@ -144,7 +150,7 @@ sub new { my $class = ref($invocant) || $invocant; my ($param) = @_; - my $user = DEFAULT_USER; + my $user = { %{ DEFAULT_USER() } }; bless ($user, $class); return $user unless $param; @@ -162,7 +168,7 @@ sub super_user { my $class = ref($invocant) || $invocant; my ($param) = @_; - my $user = dclone(DEFAULT_USER); + my $user = { %{ DEFAULT_USER() } }; $user->{groups} = [Bugzilla::Group->get_all]; $user->{bless_groups} = [Bugzilla::Group->get_all]; bless $user, $class; @@ -285,6 +291,23 @@ sub set_disabledtext { $_[0]->set('is_enabled', $_[1] ? 0 : 1); } +sub update_last_seen_date { + my $self = shift; + return unless $self->id; + my $dbh = Bugzilla->dbh; + my $date = $dbh->selectrow_array( + 'SELECT ' . $dbh->sql_date_format('NOW()', '%Y-%m-%d')); + + if (!$self->last_seen_date or $date ne $self->last_seen_date) { + $self->{last_seen_date} = $date; + # We don't use the normal update() routine here as we only + # want to update the last_seen_date column, not any other + # pending changes + $dbh->do("UPDATE profiles SET last_seen_date = ? WHERE userid = ?", + undef, $date, $self->id); + } +} + ################################################################################ # Methods ################################################################################ @@ -299,6 +322,7 @@ sub is_enabled { $_[0]->{'is_enabled'} ? 1 : 0; } sub showmybugslink { $_[0]->{showmybugslink}; } sub email_disabled { $_[0]->{disable_mail}; } sub email_enabled { !($_[0]->{disable_mail}); } +sub last_seen_date { $_[0]->{last_seen_date}; } sub cryptpassword { my $self = shift; # We don't store it because we never want it in the object (we @@ -431,6 +455,31 @@ sub tags { return $self->{tags}; } +sub bugs_ignored { + my ($self) = @_; + my $dbh = Bugzilla->dbh; + if (!defined $self->{'bugs_ignored'}) { + $self->{'bugs_ignored'} = $dbh->selectall_arrayref( + 'SELECT bugs.bug_id AS id, + bugs.bug_status AS status, + bugs.short_desc AS summary + FROM bugs + INNER JOIN email_bug_ignore + ON bugs.bug_id = email_bug_ignore.bug_id + WHERE user_id = ?', + { Slice => {} }, $self->id); + # Go ahead and load these into the visible bugs cache + # to speed up can_see_bug checks later + $self->visible_bugs([ map { $_->{'id'} } @{ $self->{'bugs_ignored'} } ]); + } + return $self->{'bugs_ignored'}; +} + +sub is_bug_ignored { + my ($self, $bug_id) = @_; + return (grep {$_->{'id'} == $bug_id} @{$self->bugs_ignored}) ? 1 : 0; +} + ########################## # Saved Recent Bug Lists # ########################## @@ -707,8 +756,8 @@ sub bless_groups { return $self->{'bless_groups'} if defined $self->{'bless_groups'}; return [] unless $self->id; - if ($self->in_group('editusers')) { - # Users having editusers permissions may bless all groups. + if ($self->in_group('admin')) { + # Users having admin permissions may bless all groups. $self->{'bless_groups'} = [Bugzilla::Group->get_all]; return $self->{'bless_groups'}; } @@ -778,6 +827,13 @@ sub in_group_id { return grep($_->id == $id, @{ $self->groups }) ? 1 : 0; } +# This is a helper to get all groups which have an icon to be displayed +# besides the name of the commenter. +sub groups_with_icon { + my $self = shift; + return $self->{groups_with_icon} //= [grep { $_->icon_url } @{ $self->direct_group_membership }]; +} + sub get_products_by_permission { my ($self, $group) = @_; # Make sure $group exists on a per-product basis. @@ -857,6 +913,14 @@ sub visible_bugs { if (@check_ids) { my $dbh = Bugzilla->dbh; my $user_id = $self->id; + + foreach my $id (@check_ids) { + my $orig_id = $id; + detaint_natural($id) + || ThrowCodeError('param_must_be_numeric', { param => $orig_id, + function => 'Bugzilla::User->visible_bugs'}); + } + my $sth; # Speed up the can_see_bug case. if (scalar(@check_ids) == 1) { @@ -1635,7 +1699,9 @@ our %names_to_events = ( 'attachments.mimetype' => EVT_ATTACHMENT_DATA, 'attachments.ispatch' => EVT_ATTACHMENT_DATA, 'dependson' => EVT_DEPEND_BLOCK, - 'blocked' => EVT_DEPEND_BLOCK); + 'blocked' => EVT_DEPEND_BLOCK, + 'product' => EVT_COMPONENT, + 'component' => EVT_COMPONENT); # Returns true if the user wants mail for a given bug change. # Note: the "+" signs before the constants suppress bareword quoting. @@ -1654,7 +1720,7 @@ sub wants_bug_mail { } else { # Catch-all for any change not caught by a more specific event - $events{+EVT_OTHER} = 1; + $events{+EVT_OTHER} = 1; } # If the user is in a particular role and the value of that role @@ -1810,6 +1876,17 @@ sub is_timetracker { return $self->{'is_timetracker'}; } +sub can_tag_comments { + my $self = shift; + + if (!defined $self->{'can_tag_comments'}) { + my $group = Bugzilla->params->{'comment_taggers_group'}; + $self->{'can_tag_comments'} = + ($group && $self->in_group($group)) ? 1 : 0; + } + return $self->{'can_tag_comments'}; +} + sub get_userlist { my $self = shift; @@ -2008,6 +2085,9 @@ sub check_and_send_account_creation_confirmation { ThrowUserError('account_creation_restricted'); } + # BMO - add a hook to allow extra validation prior to account creation. + Bugzilla::Hook::process("user_verify_login", { login => $login }); + # Create and send a token for this new account. require Bugzilla::Token; Bugzilla::Token::issue_new_user_account_token($login); @@ -2199,6 +2279,34 @@ groups. Returns a hashref with tag IDs as key, and a hashref with tag 'id', 'name' and 'bug_count' as value. +=item C<bugs_ignored> + +Returns an array of hashrefs containing information about bugs currently +being ignored by the user. + +Each hashref contains the following information: + +=over + +=item C<id> + +C<int> The id of the bug. + +=item C<status> + +C<string> The current status of the bug. + +=item C<summary> + +C<string> The current summary of the bug. + +=back + +=item C<is_bug_ignored> + +Returns true if the user does not want email notifications for the +specified bug ID, else returns false. + =back =head2 Saved Recent Bug Lists @@ -2363,7 +2471,7 @@ Determines whether or not a user is in the given group by id. Returns an arrayref of L<Bugzilla::Group> objects. The arrayref consists of the groups the user can bless, taking into account -that having editusers permissions means that you can bless all groups, and +that having admin permissions means that you can bless all groups, and that you need to be able to see a group in order to bless it. =item C<get_products_by_permission($group)> @@ -2569,6 +2677,12 @@ i.e. if the 'insidergroup' parameter is set and the user belongs to this group. Returns true if the user is a global watcher, i.e. if the 'globalwatchers' parameter contains the user. +=item C<can_tag_comments> + +Returns true if the user can attach tags to comments. +i.e. if the 'comment_taggers_group' parameter is set and the user belongs to +this group. + =back =head1 CLASS FUNCTIONS |