Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
bugzilla
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
etersoft
bugzilla
Commits
a48e3706
Commit
a48e3706
authored
Mar 29, 2000
by
dmose%mozilla.org
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
allow users to watch the bugs of other users
parent
5bfbabbd
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
626 additions
and
62 deletions
+626
-62
RelationSet.pm
Bugzilla/RelationSet.pm
+211
-0
README
README
+2
-2
RelationSet.pm
RelationSet.pm
+211
-0
bug_form.pl
bug_form.pl
+8
-2
checksetup.pl
checksetup.pl
+80
-5
defparams.pl
defparams.pl
+5
-1
globals.pl
globals.pl
+8
-19
process_bug.cgi
process_bug.cgi
+34
-33
processmail
processmail
+0
-0
userprefs.cgi
userprefs.cgi
+67
-0
No files found.
Bugzilla/RelationSet.pm
0 → 100644
View file @
a48e3706
#
# 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) 2000 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s): Dan Mosedale <dmose@mozilla.org>
# Terry Weissman <terry@mozilla.org>
# This object models a set of relations between one item and a group
# of other items. An example is the set of relations between one bug
# and the users CCed on that bug. Currently, the relation objects are
# expected to be bugzilla userids. However, this could and perhaps
# should be generalized to work with non userid objects, such as
# keywords associated with a bug. That shouldn't be hard to do; it
# might involve turning this into a virtual base class, and having
# UserSet and KeywordSet types that inherit from it.
use
diagnostics
;
use
strict
;
require
"globals.pl"
;
package
RelationSet
;
use
CGI::
Carp
qw(fatalsToBrowser)
;
# create a new empty RelationSet
#
sub
new
{
my
$type
=
shift
();
# create a ref to an empty hash and bless it
#
my
$self
=
{};
bless
$self
,
$type
;
# construct from a comma-delimited string
#
if
(
$#_
==
0
)
{
$self
->
mergeFromString
(
$_
[
0
]);
}
# unless this was a constructor for an empty list, somebody screwed up.
#
elsif
(
$#_
!=
-
1
)
{
confess
(
"invalid number of arguments"
);
}
# bless as a RelationSet
#
return
$self
;
}
# Assumes that the set of relations "FROM $table WHERE $constantSql and
# $column = $value" is currently represented by $self, and this set should
# be updated to look like $other.
#
# Returns an array of two strings, one INSERT and one DELETE, which will
# make this change. Either or both strings may be the empty string,
# meaning that no INSERT or DELETE or both (respectively) need to be done.
#
# THE CALLER IS RESPONSIBLE FOR ANY DESIRED LOCKING AND/OR CONSISTENCY
# CHECKS (not to mention doing the SendSQL() calls).
#
sub
generateSqlDeltas
{
(
$#_
==
5
)
||
confess
(
"invalid number of arguments"
);
my
(
$self
,
# instance ptr to set representing the existing state
$endState
,
# instance ptr to set representing the desired state
$table
,
# table where these relations are kept
$invariantName
,
# column held const for a RelationSet (often "bug_id")
$invariantValue
,
# what to hold the above column constant at
$columnName
# the column which varies (often a userid)
)
=
@_
;
# construct the insert list by finding relations which exist in the
# end state but not the current state.
#
my
@endStateRelations
=
keys
(
%
$endState
);
my
@insertList
=
();
foreach
(
@endStateRelations
)
{
push
(
@insertList
,
$_
)
if
(
!
exists
$$self
{
"$_"
}
);
}
# we've built the list. If it's non-null, add required sql chrome.
#
my
$sqlInsert
=
""
;
if
(
$#insertList
>
-
1
)
{
$sqlInsert
=
"INSERT INTO $table ($invariantName, $columnName) VALUES "
.
join
(
","
,
map
(
"($invariantValue, $_)"
,
@insertList
)
);
}
# construct the delete list by seeing which relations exist in the
# current state but not the end state
#
my
@selfRelations
=
keys
(
%
$self
);
my
@deleteList
=
();
foreach
(
@selfRelations
)
{
push
(
@deleteList
,
$_
)
if
(
!
exists
$$endState
{
"$_"
}
);
}
# we've built the list. if it's non-empty, add required sql chrome.
#
my
$sqlDelete
=
""
;
if
(
$#deleteList
>
-
1
)
{
$sqlDelete
=
"DELETE FROM $table WHERE $invariantName = $invariantValue "
.
"AND $columnName IN ( "
.
join
(
","
,
@deleteList
)
.
" )"
;
}
return
(
$sqlInsert
,
$sqlDelete
);
}
# compare the current object with another.
#
sub
isEqual
{
(
$#_
==
1
)
||
confess
(
"invalid number of arguments"
);
my
$self
=
shift
();
my
$other
=
shift
();
# get arrays of the keys for faster processing
#
my
@selfRelations
=
keys
(
%
$self
);
my
@otherRelations
=
keys
(
%
$other
);
# make sure the arrays are the same size
#
return
0
if
(
$#selfRelations
!=
$#otherRelations
);
# bail out if any of the elements are different
#
foreach
my
$relation
(
@selfRelations
)
{
return
0
if
(
!
exists
$$other
{
$relation
})
}
# we made it!
#
return
1
;
}
# merge the results of a SQL command into this set
#
sub
mergeFromDB
{
(
$#_
==
1
)
||
confess
(
"invalid number of arguments"
);
my
$self
=
shift
();
&::
SendSQL
(
shift
());
while
(
my
@row
=
&::
FetchSQLData
())
{
$$self
{
$row
[
0
]}
=
1
;
}
return
;
}
# merge a set in string form into this set
#
sub
mergeFromString
{
(
$#_
==
1
)
||
confess
(
"invalid number of arguments"
);
my
$self
=
shift
();
# do the merge
#
foreach
my
$person
(
split
(
/[ ,]/
,
shift
()))
{
if
(
$person
ne
""
)
{
$$self
{
&::
DBNameToIdAndCheck
(
$person
)}
=
1
;
}
}
}
# return the number of elements in this set
#
sub
size
{
my
$self
=
shift
();
my
@k
=
keys
(
%
$self
);
return
$#k
++
;
}
# return this set in array form
#
sub
toArray
{
my
$self
=
shift
();
return
keys
(
%
$self
);
}
# return this set in string form (comma-separated and sorted)
#
sub
toString
{
(
$#_
==
0
)
||
confess
(
"invalid number of arguments"
);
my
$self
=
shift
();
my
@result
=
();
foreach
my
$i
(
keys
%
$self
)
{
push
@result
,
&::
DBID_to_name
(
$i
);
}
return
join
(
','
,
sort
(
@result
));
}
README
View file @
a48e3706
...
...
@@ -26,7 +26,7 @@ other necessary ingredient is a web server set up to run cgi scripts.
The software packages necessary for the proper running of bugzilla are:
1. MySQL database server and the mysql client
1. MySQL database server and the mysql client
(3.22.5 or greater)
2. Perl (5.004 or greater)
3. DBI Perl module
4. Data::Dumper Perl module
...
...
@@ -39,7 +39,7 @@ other necessary ingredient is a web server set up to run cgi scripts.
Bugzilla has quite a few prerequisites, but none of them are TCL.
Previous versions required TCL, but it no longer needed (or used).
1.1. Getting and setting up MySQL database
1.1. Getting and setting up MySQL database
(3.22.5 or greater)
Visit MySQL homepage at http://www.mysql.org and grab the latest stable
release of the server. Both binaries and source are available and which
...
...
RelationSet.pm
0 → 100644
View file @
a48e3706
#
# 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) 2000 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s): Dan Mosedale <dmose@mozilla.org>
# Terry Weissman <terry@mozilla.org>
# This object models a set of relations between one item and a group
# of other items. An example is the set of relations between one bug
# and the users CCed on that bug. Currently, the relation objects are
# expected to be bugzilla userids. However, this could and perhaps
# should be generalized to work with non userid objects, such as
# keywords associated with a bug. That shouldn't be hard to do; it
# might involve turning this into a virtual base class, and having
# UserSet and KeywordSet types that inherit from it.
use
diagnostics
;
use
strict
;
require
"globals.pl"
;
package
RelationSet
;
use
CGI::
Carp
qw(fatalsToBrowser)
;
# create a new empty RelationSet
#
sub
new
{
my
$type
=
shift
();
# create a ref to an empty hash and bless it
#
my
$self
=
{};
bless
$self
,
$type
;
# construct from a comma-delimited string
#
if
(
$#_
==
0
)
{
$self
->
mergeFromString
(
$_
[
0
]);
}
# unless this was a constructor for an empty list, somebody screwed up.
#
elsif
(
$#_
!=
-
1
)
{
confess
(
"invalid number of arguments"
);
}
# bless as a RelationSet
#
return
$self
;
}
# Assumes that the set of relations "FROM $table WHERE $constantSql and
# $column = $value" is currently represented by $self, and this set should
# be updated to look like $other.
#
# Returns an array of two strings, one INSERT and one DELETE, which will
# make this change. Either or both strings may be the empty string,
# meaning that no INSERT or DELETE or both (respectively) need to be done.
#
# THE CALLER IS RESPONSIBLE FOR ANY DESIRED LOCKING AND/OR CONSISTENCY
# CHECKS (not to mention doing the SendSQL() calls).
#
sub
generateSqlDeltas
{
(
$#_
==
5
)
||
confess
(
"invalid number of arguments"
);
my
(
$self
,
# instance ptr to set representing the existing state
$endState
,
# instance ptr to set representing the desired state
$table
,
# table where these relations are kept
$invariantName
,
# column held const for a RelationSet (often "bug_id")
$invariantValue
,
# what to hold the above column constant at
$columnName
# the column which varies (often a userid)
)
=
@_
;
# construct the insert list by finding relations which exist in the
# end state but not the current state.
#
my
@endStateRelations
=
keys
(
%
$endState
);
my
@insertList
=
();
foreach
(
@endStateRelations
)
{
push
(
@insertList
,
$_
)
if
(
!
exists
$$self
{
"$_"
}
);
}
# we've built the list. If it's non-null, add required sql chrome.
#
my
$sqlInsert
=
""
;
if
(
$#insertList
>
-
1
)
{
$sqlInsert
=
"INSERT INTO $table ($invariantName, $columnName) VALUES "
.
join
(
","
,
map
(
"($invariantValue, $_)"
,
@insertList
)
);
}
# construct the delete list by seeing which relations exist in the
# current state but not the end state
#
my
@selfRelations
=
keys
(
%
$self
);
my
@deleteList
=
();
foreach
(
@selfRelations
)
{
push
(
@deleteList
,
$_
)
if
(
!
exists
$$endState
{
"$_"
}
);
}
# we've built the list. if it's non-empty, add required sql chrome.
#
my
$sqlDelete
=
""
;
if
(
$#deleteList
>
-
1
)
{
$sqlDelete
=
"DELETE FROM $table WHERE $invariantName = $invariantValue "
.
"AND $columnName IN ( "
.
join
(
","
,
@deleteList
)
.
" )"
;
}
return
(
$sqlInsert
,
$sqlDelete
);
}
# compare the current object with another.
#
sub
isEqual
{
(
$#_
==
1
)
||
confess
(
"invalid number of arguments"
);
my
$self
=
shift
();
my
$other
=
shift
();
# get arrays of the keys for faster processing
#
my
@selfRelations
=
keys
(
%
$self
);
my
@otherRelations
=
keys
(
%
$other
);
# make sure the arrays are the same size
#
return
0
if
(
$#selfRelations
!=
$#otherRelations
);
# bail out if any of the elements are different
#
foreach
my
$relation
(
@selfRelations
)
{
return
0
if
(
!
exists
$$other
{
$relation
})
}
# we made it!
#
return
1
;
}
# merge the results of a SQL command into this set
#
sub
mergeFromDB
{
(
$#_
==
1
)
||
confess
(
"invalid number of arguments"
);
my
$self
=
shift
();
&::
SendSQL
(
shift
());
while
(
my
@row
=
&::
FetchSQLData
())
{
$$self
{
$row
[
0
]}
=
1
;
}
return
;
}
# merge a set in string form into this set
#
sub
mergeFromString
{
(
$#_
==
1
)
||
confess
(
"invalid number of arguments"
);
my
$self
=
shift
();
# do the merge
#
foreach
my
$person
(
split
(
/[ ,]/
,
shift
()))
{
if
(
$person
ne
""
)
{
$$self
{
&::
DBNameToIdAndCheck
(
$person
)}
=
1
;
}
}
}
# return the number of elements in this set
#
sub
size
{
my
$self
=
shift
();
my
@k
=
keys
(
%
$self
);
return
$#k
++
;
}
# return this set in array form
#
sub
toArray
{
my
$self
=
shift
();
return
keys
(
%
$self
);
}
# return this set in string form (comma-separated and sorted)
#
sub
toString
{
(
$#_
==
0
)
||
confess
(
"invalid number of arguments"
);
my
$self
=
shift
();
my
@result
=
();
foreach
my
$i
(
keys
%
$self
)
{
push
@result
,
&::
DBID_to_name
(
$i
);
}
return
join
(
','
,
sort
(
@result
));
}
bug_form.pl
View file @
a48e3706
...
...
@@ -22,6 +22,8 @@
use
diagnostics
;
use
strict
;
use
RelationSet
;
# Shut up misguided -w warnings about "used only once". For some reason,
# "use vars" chokes on me when I try it here.
...
...
@@ -147,8 +149,10 @@ my $sev_popup = make_options(\@::legal_severity, $bug{'bug_severity'});
my
$component_popup
=
make_options
(
$::components
{
$bug
{
'product'
}},
$bug
{
'component'
});
my
$ccSet
=
new
RelationSet
;
$ccSet
->
mergeFromDB
(
"select who from cc where bug_id=$id"
);
my
$cc_element
=
'<INPUT NAME=cc SIZE=30 VALUE="'
.
ShowCcList
(
$id
)
.
'">'
;
$ccSet
->
toString
(
)
.
'">'
;
my
$URL
=
$bug
{
'bug_file_loc'
};
...
...
@@ -208,7 +212,9 @@ if (Param("usetargetmilestone")) {
if
(
$url
eq
""
)
{
$url
=
"notargetmilestone.html"
;
}
if
(
$bug
{
'target_milestone'
}
eq
""
)
{
$bug
{
'target_milestone'
}
=
" "
;
}
print
"
<TD ALIGN=RIGHT><A href=\"$url\"><B>Target Milestone:</B></A></TD>
<TD><SELECT NAME=target_milestone>"
.
...
...
checksetup.pl
View file @
a48e3706
...
...
@@ -20,6 +20,7 @@
#
# Contributor(s): Holger Schurig <holgerschurig@nikocity.de>
# Terry Weissman <terry@mozilla.org>
# Dan Mosedale <dmose@mozilla.org>
#
#
# Direct any questions on this source code to
...
...
@@ -591,8 +592,15 @@ $table{cc} =
'bug_id mediumint not null,
who mediumint not null,
index(bug_id),
index(who)'
;
index(who),
unique(bug_id,who)'
;
$table
{
watch
}
=
'watcher mediumint not null,
watched mediumint not null,
index(watched),
unique(watcher,watched)'
;
$table
{
longdescs
}
=
...
...
@@ -742,8 +750,8 @@ $table{keywords} =
'bug_id mediumint not null,
keywordid smallint not null,
index(
bug_
id),
index(
keywordid)'
;
index(
keyword
id),
unique(bug_id,
keywordid)'
;
$table
{
keyworddefs
}
=
'id smallint not null primary key,
...
...
@@ -994,6 +1002,49 @@ sub GetIndexDef ($$)
}
}
sub
CountIndexes
($)
{
my
(
$table
)
=
@_
;
my
$sth
=
$dbh
->
prepare
(
"SHOW INDEX FROM $table"
);
$sth
->
execute
;
if
(
$sth
->
rows
==
-
1
)
{
die
(
"Unexpected response while counting indexes in $table:"
.
" \$sth->rows == -1"
);
}
return
(
$sth
->
rows
);
}
sub
DropIndexes
($)
{
my
(
$table
)
=
@_
;
my
%
SEEN
;
# get the list of indexes
#
my
$sth
=
$dbh
->
prepare
(
"SHOW INDEX FROM $table"
);
$sth
->
execute
;
# drop each index
#
while
(
my
$ref
=
$sth
->
fetchrow_arrayref
)
{
# note that some indexes are described by multiple rows in the
# index table, so we may have already dropped the index described
# in the current row.
#
next
if
exists
$SEEN
{
$$ref
[
2
]};
my
$dropSth
=
$dbh
->
prepare
(
"ALTER TABLE $table DROP INDEX $$ref[2]"
);
$dropSth
->
execute
;
$dropSth
->
finish
;
$SEEN
{
$$ref
[
2
]}
=
1
;
}
}
#
# Check if the enums in the bugs table return the same values that are defined
# in the various locally changeable variables. If this is true, then alter the
...
...
@@ -1506,7 +1557,6 @@ AddField('products', 'maxvotesperbug', 'smallint not null default 10000');
AddField
(
'products'
,
'votestoconfirm'
,
'smallint not null'
);
AddField
(
'profiles'
,
'blessgroupset'
,
'bigint not null'
);
# 2000-03-21 Adding a table for target milestones to
# database - matthew@zeroknowledge.com
...
...
@@ -1577,6 +1627,29 @@ if (!GetFieldDef('products', 'defaultmilestone')) {
}
}
# 2000-03-24 Added unique indexes into the cc and keyword tables. This
# prevents certain database inconsistencies, and, moreover, is required for
# new generalized list code to work.
if
(
CountIndexes
(
'cc'
)
!=
3
)
{
# XXX should eliminate duplicate entries before altering
#
print
"Recreating indexes on cc table.\n"
;
DropIndexes
(
'cc'
);
$dbh
->
do
(
"ALTER TABLE cc ADD UNIQUE (bug_id,who)"
);
$dbh
->
do
(
"ALTER TABLE cc ADD INDEX (who)"
);
}
if
(
CountIndexes
(
'keywords'
)
!=
3
)
{
# XXX should eliminate duplicate entries before altering
#
print
"Recreating indexes on keywords table.\n"
;
DropIndexes
(
'keywords'
);
$dbh
->
do
(
"ALTER TABLE keywords ADD INDEX (keywordid)"
);
$dbh
->
do
(
"ALTER TABLE keywords ADD UNIQUE (bug_id,keywordid)"
);
}
#
# If you had to change the --TABLE-- definition in any way, then add your
...
...
@@ -1594,4 +1667,6 @@ if ($regenerateshadow) {
print
"Now regenerating the shadow database for all bugs.\n"
;
system
(
"./processmail regenerate"
);
}
unlink
"data/versioncache"
;
print
"Reminder: Bugzilla now requires version 3.22.5 or later of MySQL.\n"
;
defparams.pl
View file @
a48e3706
...
...
@@ -550,6 +550,10 @@ DefParam("commentonclose",
DefParam
(
"commentonduplicate"
,
"If this option is on, the user needs to enter a short comment if the bug is marked as duplicate"
,
"b"
,
0
);
DefParam
(
"supportwatchers"
,
"Support one user watching (ie getting copies of all related email"
.
" about) another's bugs. Useful for people going on vacation, and"
.
" QA folks watching particular developers' bugs"
,
"b"
,
0
);
1
;
globals.pl
View file @
a48e3706
...
...
@@ -18,6 +18,7 @@
# Rights Reserved.
#
# Contributor(s): Terry Weissman <terry@mozilla.org>
# Dan Mosedale <dmose@mozilla.org>
# Contains some global variables and routines used throughout bugzilla.
...
...
@@ -65,6 +66,7 @@ use Mysql;
use
Date::
Format
;
# For time2str().
use
Date::
Parse
;
# For str2time().
# use Carp; # for confess
use
RelationSet
;
# Contains the version string for the current running Bugzilla.
$::param
{
'version'
}
=
'2.9'
;
...
...
@@ -118,9 +120,6 @@ sub SqlLog {
}
}
sub
SendSQL
{
my
(
$str
,
$dontshadow
)
=
(
@_
);
my
$iswrite
=
(
$str
=~
/^(INSERT|REPLACE|UPDATE|DELETE)/i
);
...
...
@@ -756,23 +755,13 @@ sub GetLongDescriptionAsHTML {
}
sub
ShowCcList
{
my
(
$num
)
=
(
@_
);
my
@ccids
;
my
@row
;
SendSQL
(
"select who from cc where bug_id = $num"
);
while
(
@row
=
FetchSQLData
())
{
push
(
@ccids
,
$row
[
0
]);
}
my
@result
=
();
foreach
my
$i
(
@ccids
)
{
push
@result
,
DBID_to_name
(
$i
);
}
return
join
(
','
,
@result
);
my
(
$num
)
=
(
@_
);
my
$ccSet
=
new
RelationSet
();
$ccSet
->
mergeFromDB
(
"select who from cc where bug_id=$num"
);
return
$ccSet
->
toString
();
}
# Fills in a hashtable with info about the columns for the given table in the
# database. The hashtable has the following entries:
# -list- the list of column names
...
...
@@ -903,7 +892,7 @@ sub RemoveVotes {
}
sub
Param
{
sub
Param
($)
{
my
(
$value
)
=
(
@_
);
if
(
defined
$::param
{
$value
})
{
return
$::param
{
$value
};
...
...
process_bug.cgi
View file @
a48e3706
...
...
@@ -28,6 +28,7 @@ my $UserInEditGroupSet = -1;
my
$UserInCanConfirmGroupSet
=
-
1
;
require
"CGI.pl"
;
use
RelationSet
;
# Shut up misguided -w warnings about "used only once":
...
...
@@ -373,24 +374,21 @@ if (defined $::FORM{'qa_contact'}) {
ConnectToDatabase
();
my
%
ccids
;
my
$origcclist
=
""
;
my
$formCcSet
=
new
RelationSet
;
my
$origCcSet
=
new
RelationSet
;
my
$origCcString
;
# We make sure to check out the CC list before we actually start touching any
# bugs.
# bugs. mergeFromString() ultimately searches the database using a quoted
# form of the data it gets from $::FORM{'cc'}, so anything bogus from a
# security standpoint should trigger an abort there.
#
if
(
defined
$::FORM
{
'cc'
}
&&
defined
$::FORM
{
'id'
})
{
$origcclist
=
ShowCcList
(
$::FORM
{
'id'
});
if
(
$origcclist
ne
$::FORM
{
'cc'
})
{
foreach
my
$person
(
split
(
/[ ,]/
,
$::FORM
{
'cc'
}))
{
if
(
$person
ne
""
)
{
my
$cid
=
DBNameToIdAndCheck
(
$person
);
$ccids
{
$cid
}
=
1
;
}
}
}
$origCcSet
->
mergeFromDB
(
"select who from cc where bug_id = $::FORM{'id'}"
);
$origCcString
=
$origCcSet
->
toString
();
# cache a copy of the string vers
$formCcSet
->
mergeFromString
(
$::FORM
{
'cc'
});
}
if
(
Param
(
'strictvaluechecks'
)
)
{
CheckFormFieldDefined
(
\%::
FORM
,
'knob'
);
}
...
...
@@ -759,22 +757,25 @@ The changes made were:
AppendComment
(
$id
,
$::FORM
{
'who'
},
$::FORM
{
'comment'
});
}
if
(
defined
$::FORM
{
'cc'
}
&&
$origcclist
ne
$::FORM
{
'cc'
})
{
SendSQL
(
"delete from cc where bug_id = $id"
);
foreach
my
$ccid
(
keys
%
ccids
)
{
SendSQL
(
"insert into cc (bug_id, who) values ($id, $ccid)"
);
}
my
$newcclist
=
ShowCcList
(
$id
);
if
(
$newcclist
ne
$origcclist
)
{
my
$col
=
GetFieldID
(
'cc'
);
my
$origq
=
SqlQuote
(
$origcclist
);
my
$newq
=
SqlQuote
(
$newcclist
);
SendSQL
(
"INSERT INTO bugs_activity "
.
"(bug_id,who,bug_when,fieldid,oldvalue,newvalue) VALUES "
.
"($id,$whoid,'$timestamp',$col,$origq,$newq)"
);
}
}
if
(
defined
$::FORM
{
'cc'
}
&&
defined
$::FORM
{
'id'
}
&&
!
$origCcSet
->
isEqual
(
$formCcSet
)
)
{
# update the database to look like the form
#
my
@CCDELTAS
=
$origCcSet
->
generateSqlDeltas
(
$formCcSet
,
"cc"
,
"bug_id"
,
$::FORM
{
'id'
},
"who"
);
$CCDELTAS
[
0
]
eq
""
||
SendSQL
(
$CCDELTAS
[
0
]);
$CCDELTAS
[
1
]
eq
""
||
SendSQL
(
$CCDELTAS
[
1
]);
my
$col
=
GetFieldID
(
'cc'
);
my
$origq
=
SqlQuote
(
$origCcString
);
my
$newq
=
SqlQuote
(
$::FORM
{
'cc'
});
SendSQL
(
"INSERT INTO bugs_activity "
.
"(bug_id,who,bug_when,fieldid,oldvalue,newvalue) VALUES "
.
"($id,$whoid,'$timestamp',$col,$origq,$newq)"
);
}
if
(
defined
$::FORM
{
'dependson'
})
{
my
$me
=
"blocked"
;
...
...
@@ -850,9 +851,9 @@ The changes made were:
if
(
$col
eq
'assigned_to'
||
$col
eq
'qa_contact'
)
{
$old
=
DBID_to_name
(
$old
)
if
$old
!=
0
;
$new
=
DBID_to_name
(
$new
)
if
$new
!=
0
;
$orig
cclist
.=
",$old"
;
# make sure to send mail to people
# if they are going to no longer get
# updates about this bug.
$orig
CcString
.=
",$old"
;
# make sure to send mail to people
# if they are going to no longer get
# updates about this bug.
}
if
(
$col
eq
'product'
)
{
RemoveVotes
(
$id
,
0
,
...
...
@@ -869,7 +870,7 @@ The changes made were:
print
"<TABLE BORDER=1><TD><H2>Changes to bug $id submitted</H2>\n"
;
SendSQL
(
"unlock tables"
);
system
(
"./processmail"
,
"-forcecc"
,
$orig
cclist
,
$id
,
$::FORM
{
'who'
});
system
(
"./processmail"
,
"-forcecc"
,
$orig
CcString
,
$id
,
$::FORM
{
'who'
});
print
"<TD><A HREF=\"show_bug.cgi?id=$id\">Back To BUG# $id</A></TABLE>\n"
;
foreach
my
$k
(
keys
(
%
dependencychanged
))
{
...
...
processmail
View file @
a48e3706
This diff is collapsed.
Click to expand it.
userprefs.cgi
View file @
a48e3706
...
...
@@ -14,12 +14,15 @@
# The Original Code is the Bugzilla Bug Tracking System.
#
# Contributor(s): Terry Weissman <terry@mozilla.org>
# Dan Mosedale <dmose@mozilla.org>
use
diagnostics
;
use
strict
;
require
"CGI.pl"
;
use
RelationSet
;
# Shut up misguided -w warnings about "used only once". "use vars" just
# doesn't work for me.
sub
sillyness
{
...
...
@@ -134,6 +137,29 @@ risk any bugs), check here.
EmitEntry
(
"Check here to sign up (and risk any bugs)"
,
qq{<INPUT TYPE="checkbox" NAME="newemailtech" $checkedpart>New email tech}
);
}
if
(
Param
(
"supportwatchers"
))
{
my
$watcheduserSet
=
new
RelationSet
;
$watcheduserSet
->
mergeFromDB
(
"SELECT watched FROM watch WHERE"
.
" watcher=$userid"
);
my
$watchedusers
=
$watcheduserSet
->
toString
();
print
qq{
<TR><TD COLSPAN="2"><HR></TD></TR>
<TR><TD COLSPAN="2"><FONT COLOR="red">New!</FONT>
If you want to help cover for someone when they're on vacation, or if
you need to do the QA related to all of their bugs, you can tell bugzilla
to send mail related to their bugs to you also. List the email addresses
of any users you wish to watch here, separated by commas.
<FONT COLOR="red">Note that you MUST have the above "New email tech"
button selected in order to use this feature.</FONT>
</TD></TR>
}
;
EmitEntry
(
"Users to watch"
,
qq{<INPUT SIZE=35 NAME="watchedusers" VALUE="$watchedusers">}
);
}
}
sub
SaveDiffs
{
...
...
@@ -144,6 +170,47 @@ sub SaveDiffs {
SendSQL
(
"UPDATE profiles "
.
"SET emailnotification = "
.
SqlQuote
(
$::FORM
{
'emailnotification'
})
.
", newemailtech = $newemailtech WHERE userid = $userid"
);
# deal with any watchers
#
if
(
Param
(
"supportwatchers"
)
)
{
if
(
exists
$::FORM
{
'watchedusers'
})
{
Error
(
'You must have "New email tech" set to watch someone'
)
if
(
$::FORM
{
'watchedusers'
}
ne
""
&&
$newemailtech
==
0
);
# Just in case. Note that this much locking is actually overkill:
# we don't really care if anyone reads the watch table. So
# some small amount of contention could be gotten rid of by
# using user-defined locks rather than table locking.
#
SendSQL
(
"LOCK TABLES watch WRITE, profiles READ"
);
# what the db looks like now
#
my
$origWatchedUsers
=
new
RelationSet
;
$origWatchedUsers
->
mergeFromDB
(
"SELECT watched FROM watch WHERE"
.
" watcher=$userid"
);
# update the database to look like the form
#
my
$newWatchedUsers
=
new
RelationSet
(
$::FORM
{
'watchedusers'
});
my
@CCDELTAS
=
$origWatchedUsers
->
generateSqlDeltas
(
$newWatchedUsers
,
"watch"
,
"watcher"
,
$userid
,
"watched"
);
$CCDELTAS
[
0
]
eq
""
||
SendSQL
(
$CCDELTAS
[
0
]);
$CCDELTAS
[
1
]
eq
""
||
SendSQL
(
$CCDELTAS
[
1
]);
# all done
#
SendSQL
(
"UNLOCK TABLES"
);
}
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment