summaryrefslogtreecommitdiffstats
path: root/Bugzilla/User.pm
blob: 72870d544e6203b91637193079683526afd759d6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
# -*- Mode: perl; indent-tabs-mode: nil -*-
#
# The contents of this file are subject to the Mozilla Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Original Code is the Bugzilla Bug Tracking System.
#
# The Initial Developer of the Original Code is Netscape Communications
# Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s): Myk Melez <myk@mozilla.org>

################################################################################
# Module Initialization
################################################################################

# Make it harder for us to do dangerous things in Perl.
use strict;

# This module implements utilities for dealing with Bugzilla users.
package Bugzilla::User;

################################################################################
# Functions
################################################################################

my $user_cache = {};
sub new {
    # Returns a hash of information about a particular user.

    my $invocant = shift;
    my $class = ref($invocant) || $invocant;
  
    my $exists = 1;
    my ($id, $name, $email) = @_;
    
    return undef if !$id;
    return $user_cache->{$id} if exists($user_cache->{$id});
    
    my $self = { 'id' => $id };
    
    bless($self, $class);
    
    if (!$name && !$email) {
        &::PushGlobalSQLState();
        &::SendSQL("SELECT 1, realname, login_name FROM profiles WHERE userid = $id");
        ($exists, $name, $email) = &::FetchSQLData();
        &::PopGlobalSQLState();
    }
    
    $self->{'name'} = $name;
    $self->{'email'} = $email;
    $self->{'exists'} = $exists;
        
    # Generate a string to identify the user by name + email if the user
    # has a name or by email only if she doesn't.
    $self->{'identity'} = $name ? "$name <$email>" : $email;

    # Generate a user "nickname" -- i.e. a shorter, not-necessarily-unique name 
    # by which to identify the user.  Currently the part of the user's email
    # address before the at sign (@), but that could change, especially if we
    # implement usernames not dependent on email address.
    my @email_components = split("@", $email);
    $self->{'nick'} = $email_components[0];
    
    $user_cache->{$id} = $self;
    
    return $self;
}

sub match {
    # Generates a list of users whose login name (email address) or real name
    # matches a substring.

    # $str contains the string to match against, while $limit contains the
    # maximum number of records to retrieve.
    my ($str, $limit, $exclude_disabled) = @_;
    
    # Build the query.
    my $sqlstr = &::SqlQuote($str);
    my $qry = "
          SELECT  userid, realname, login_name
            FROM  profiles
           WHERE  (INSTR(login_name, $sqlstr) OR INSTR(realname, $sqlstr))
    ";
    $qry .= "AND disabledtext = '' " if $exclude_disabled;
    $qry .= "ORDER BY realname, login_name ";
    $qry .= "LIMIT $limit " if $limit;

    # Execute the query, retrieve the results, and make them into User objects.
    my @users;
    &::PushGlobalSQLState();
    &::SendSQL($qry);
    push(@users, new Bugzilla::User(&::FetchSQLData())) while &::MoreSQLData();
    &::PopGlobalSQLState();

    return \@users;
}

sub email_prefs {
    # Get or set (not implemented) the user's email notification preferences.
    
    my $self = shift;
    
    # If the calling code is setting the email preferences, update the object
    # but don't do anything else.  This needs to write email preferences back
    # to the database.
    if (@_) { $self->{email_prefs} = shift; return; }
    
    # If we already got them from the database, return the existing values.
    return $self->{email_prefs} if $self->{email_prefs};
    
    # Retrieve the values from the database.
    &::SendSQL("SELECT emailflags FROM profiles WHERE userid = $self->{id}");
    my ($flags) = &::FetchSQLData();

    my @roles = qw(Owner Reporter QAcontact CClist Voter);
    my @reasons = qw(Removeme Comments Attachments Status Resolved Keywords 
                     CC Other Unconfirmed);

    # If the prefs are empty, this user hasn't visited the email pane
    # of userprefs.cgi since before the change to use the "emailflags" 
    # column, so initialize that field with the default prefs.
    if (!$flags) {
        # Create a default prefs string that causes the user to get all email.
        $flags = "ExcludeSelf~on~FlagRequestee~on~FlagRequester~on~";
        foreach my $role (@roles) {
            foreach my $reason (@reasons) {
                $flags .= "email$role$reason~on~";
            }
        }
        chop $flags;
    }

    # Convert the prefs from the flags string from the database into
    # a Perl record.  The 255 param is here because split will trim 
    # any trailing null fields without a third param, which causes Perl 
    # to eject lots of warnings. Any suitably large number would do.
    my $prefs = { split(/~/, $flags, 255) };
    
    # Determine the value of the "excludeself" global email preference.
    # Note that the value of "excludeself" is assumed to be off if the
    # preference does not exist in the user's list, unlike other 
    # preferences whose value is assumed to be on if they do not exist.
    $prefs->{ExcludeSelf} = 
      exists($prefs->{ExcludeSelf}) && $prefs->{ExcludeSelf} eq "on";
    
    # Determine the value of the global request preferences.
    foreach my $pref qw(FlagRequestee FlagRequester) {
        $prefs->{$pref} = !exists($prefs->{$pref}) || $prefs->{$pref} eq "on";
    }
    
    # Determine the value of the rest of the preferences by looping over
    # all roles and reasons and converting their values to Perl booleans.
    foreach my $role (@roles) {
        foreach my $reason (@reasons) {
            my $key = "email$role$reason";
            $prefs->{$key} = !exists($prefs->{$key}) || $prefs->{$key} eq "on";
        }
    }

    $self->{email_prefs} = $prefs;
    
    return $self->{email_prefs};
}

1;