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
7d1af605
Commit
7d1af605
authored
Oct 25, 2002
by
bugreport%peshkin.net
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Bug 162990 Shorthand/wildcard entry for login names in assign, cc, qa, fields
patch by not_erik@dasbistro.com r=joel, myk
parent
80b04d87
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
299 additions
and
19 deletions
+299
-19
User.pm
Bugzilla/User.pm
+242
-19
defparams.pl
defparams.pl
+33
-0
post_bug.cgi
post_bug.cgi
+8
-0
process_bug.cgi
process_bug.cgi
+10
-0
code-error.html.tmpl
template/en/default/global/code-error.html.tmpl
+4
-0
field-descs.html.tmpl
template/en/default/global/field-descs.html.tmpl
+2
-0
No files found.
Bugzilla/User.pm
View file @
7d1af605
...
...
@@ -18,6 +18,7 @@
# Rights Reserved.
#
# Contributor(s): Myk Melez <myk@mozilla.org>
# Erik Stambaugh <not_erik@dasbistro.com>
################################################################################
# Module Initialization
...
...
@@ -79,33 +80,255 @@ sub new {
sub
match
{
# Generates a list of users whose login name (email address) or real name
# matches a substring.
# matches a substring
or wildcard
.
# $str contains the string to match
against
, while $limit contains the
# $str contains the string to match, 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
();
my
@users
=
();
return
\
@users
if
$str
=~
/^\s*$/
;
# The search order is wildcards, then exact match, then INSTR search.
# Wildcard matching is skipped if there is no '*', and exact matches will
# not (?) have a '*' in them. If any search comes up with something, the
# ones following it will not execute.
# first try wildcards
my
$wildstr
=
$str
;
if
(
$wildstr
=~
s/\*/\%/g
)
{
# don't do wildcards if no '*' in the string
# Build the query.
my
$sqlstr
=
&::
SqlQuote
(
$wildstr
);
my
$query
=
"SELECT userid, realname, login_name "
.
"FROM profiles "
.
"WHERE (login_name LIKE $sqlstr "
.
"OR realname LIKE $sqlstr) "
;
$query
.=
"AND disabledtext = '' "
if
$exclude_disabled
;
$query
.=
"ORDER BY length(login_name) "
;
$query
.=
"LIMIT $limit "
if
$limit
;
# Execute the query, retrieve the results, and make them into
# User objects.
&::
PushGlobalSQLState
();
&::
SendSQL
(
$query
);
push
(
@users
,
new
Bugzilla::
User
(
&::
FetchSQLData
()))
while
&::
MoreSQLData
();
&::
PopGlobalSQLState
();
}
else
{
# try an exact match
my
$sqlstr
=
&::
SqlQuote
(
$str
);
my
$query
=
"SELECT userid, realname, login_name "
.
"FROM profiles "
.
"WHERE login_name = $sqlstr "
;
$query
.=
"AND disabledtext = '' "
if
$exclude_disabled
;
&::
PushGlobalSQLState
();
&::
SendSQL
(
$query
);
push
(
@users
,
new
Bugzilla::
User
(
&::
FetchSQLData
()))
if
&::
MoreSQLData
();
&::
PopGlobalSQLState
();
}
# then try instr
if
((
scalar
(
@users
)
==
0
)
&&
(
&::
Param
(
'usermatchmode'
)
eq
'search'
)
&&
(
length
(
$str
)
>=
3
))
{
my
$sqlstr
=
&::
SqlQuote
(
$str
);
my
$query
=
"SELECT userid, realname, login_name "
.
"FROM profiles "
.
"WHERE (INSTR(login_name, $sqlstr) "
.
"OR INSTR(realname, $sqlstr)) "
;
$query
.=
"AND disabledtext = '' "
if
$exclude_disabled
;
$query
.=
"ORDER BY length(login_name) "
;
$query
.=
"LIMIT $limit "
if
$limit
;
&::
PushGlobalSQLState
();
&::
SendSQL
(
$query
);
push
(
@users
,
new
Bugzilla::
User
(
&::
FetchSQLData
()))
while
&::
MoreSQLData
();
&::
PopGlobalSQLState
();
}
# order @users by alpha
@users
=
sort
{
uc
(
$a
->
{
'email'
})
cmp
uc
(
$b
->
{
'email'
})
}
@users
;
return
\
@users
;
}
# match_field() is a CGI wrapper for the match() function.
#
# Here's what it does:
#
# 1. Accepts a list of fields along with whether they may take multiple values
# 2. Takes the values of those fields from $::FORM and passes them to match()
# 3. Checks the results of the match and displays confirmation or failure
# messages as appropriate.
#
# The confirmation screen functions the same way as verify-new-product and
# confirm-duplicate, by rolling all of the state information into a
# form which is passed back, but in this case the searched fields are
# replaced with the search results.
#
# The act of displaying the confirmation or failure messages means it must
# throw a template and terminate. When confirmation is sent, all of the
# searchable fields have been replaced by exact fields and the calling script
# is executed as normal.
#
# match_field must be called early in a script, before anything external is
# done with the form data.
#
# In order to do a simple match without dealing with templates, confirmation,
# or globals, simply calling Bugzilla::User::match instead will be
# sufficient.
# How to call it:
#
# Bugzilla::User::match_field ({
# 'field_name' => { 'type' => fieldtype },
# 'field_name2' => { 'type' => fieldtype },
# [...]
# });
#
# fieldtype can be either 'single' or 'multi'.
#
sub
match_field
{
my
$fields
=
shift
;
# arguments as a hash
my
$matches
=
{};
# the values sent to the template
my
$matchsuccess
=
1
;
# did the match fail?
my
$need_confirm
=
0
;
# whether to display confirmation screen
# prepare default form values
my
$vars
=
$::vars
;
$vars
->
{
'form'
}
=
\%::
FORM
;
$vars
->
{
'mform'
}
=
\%::
MFORM
;
# Skip all of this if the option has been turned off
return
1
if
(
&::
Param
(
'usermatchmode'
)
eq
'off'
);
for
my
$field
(
keys
%
{
$fields
})
{
# Tolerate fields that do not exist.
#
# This is so that fields like qa_contact can be specified in the code
# and it won't break if $::MFORM does not define them.
#
# It has the side-effect that if a bad field name is passed it will be
# quietly ignored rather than raising a code error.
next
if
!
defined
(
$vars
->
{
'mform'
}
->
{
$field
});
# We need to move the query to $raw_field, where it will be split up,
# modified by the search, and put back into $::FORM and $::MFORM
# incrementally.
my
$raw_field
=
join
(
" "
,
@
{
$vars
->
{
'mform'
}
->
{
$field
}});
$vars
->
{
'form'
}
->
{
$field
}
=
''
;
$vars
->
{
'mform'
}
->
{
$field
}
=
[]
;
my
@queries
=
();
# Now we either split $raw_field by spaces/commas and put the list
# into @queries, or in the case of fields which only accept single
# entries, we simply use the verbatim text.
$raw_field
=~
s/^\s+|\s+$//sg
;
# trim leading/trailing space
# single field
if
(
$fields
->
{
$field
}
->
{
'type'
}
eq
'single'
)
{
@queries
=
(
$raw_field
)
unless
$raw_field
=~
/^\s*$/
;
# multi-field
}
elsif
(
$fields
->
{
$field
}
->
{
'type'
}
eq
'multi'
)
{
@queries
=
split
(
/[\s,]+/
,
$raw_field
);
}
else
{
# bad argument
$vars
->
{
'argument'
}
=
$fields
->
{
$field
}
->
{
'type'
};
$vars
->
{
'function'
}
=
'Bugzilla::User::match_field'
;
&::
ThrowCodeError
(
'bad_arg'
);
}
for
my
$query
(
@queries
)
{
my
$users
=
match
(
$query
,
# match string
(
&::
Param
(
'maxusermatches'
)
||
0
)
+
1
,
# match limit
1
# exclude_disabled
);
# skip confirmation for exact matches
if
((
scalar
(
@
{
$users
})
==
1
)
&&
(
@
{
$users
}[
0
]
->
{
'email'
}
eq
$query
))
{
$vars
->
{
'form'
}
->
{
$field
}
.=
@
{
$users
}[
0
]
->
{
'email'
}
.
" "
;
push
@
{
$vars
->
{
'mform'
}
->
{
$field
}},
@
{
$users
}[
0
]
->
{
'email'
}
.
" "
;
next
;
}
$matches
->
{
$field
}
->
{
$query
}
->
{
'users'
}
=
$users
;
$matches
->
{
$field
}
->
{
$query
}
->
{
'status'
}
=
'success'
;
$matches
->
{
$field
}
->
{
$query
}
->
{
'selecttype'
}
=
$fields
->
{
$field
}
->
{
'type'
};
# here is where it checks for multiple matches
if
(
scalar
(
@
{
$users
})
==
1
)
{
# exactly one match
$vars
->
{
'form'
}
->
{
$field
}
.=
@
{
$users
}[
0
]
->
{
'email'
}
.
" "
;
push
@
{
$vars
->
{
'mform'
}
->
{
$field
}},
@
{
$users
}[
0
]
->
{
'email'
}
.
" "
;
$need_confirm
=
1
if
&::
Param
(
'confirmuniqueusermatch'
);
}
elsif
((
scalar
(
@
{
$users
})
>
1
)
&&
(
&::
Param
(
'maxusermatches'
)
!=
1
))
{
$need_confirm
=
1
;
if
((
&::
Param
(
'maxusermatches'
))
&&
(
scalar
(
@
{
$users
})
>
&::
Param
(
'maxusermatches'
)))
{
$matches
->
{
$field
}
->
{
$query
}
->
{
'status'
}
=
'trunc'
;
pop
@
{
$users
};
# take the last one out
}
}
else
{
# everything else fails
$matchsuccess
=
0
;
# fail
$matches
->
{
$field
}
->
{
$query
}
->
{
'status'
}
=
'fail'
;
$need_confirm
=
1
;
# confirmation screen shows failures
}
}
}
return
1
unless
$need_confirm
;
# skip confirmation if not needed.
$vars
->
{
'script'
}
=
$ENV
{
'SCRIPT_NAME'
};
# for self-referencing URLs
$vars
->
{
'matches'
}
=
$matches
;
# matches that were made
$vars
->
{
'matchsuccess'
}
=
$matchsuccess
;
# continue or fail
print
"Content-type: text/html\n\n"
;
$::template
->
process
(
"global/confirm-user-match.html.tmpl"
,
$vars
)
||
&::
ThrowTemplateError
(
$::template
->
error
());
exit
;
}
sub
email_prefs
{
# Get or set (not implemented) the user's email notification preferences.
...
...
defparams.pl
View file @
7d1af605
...
...
@@ -879,6 +879,39 @@ Reason: %reason%
default
=>
'32'
,
checker
=>
\&
check_netmask
},
{
name
=>
'usermatchmode'
,
desc
=>
'Allow match strings to be entered for user names when entering '
.
'and editing bugs. <p>'
.
'"off" disables matching,<br> '
.
'"wildcard" allows only wildcards,<br> '
.
'and "search" allows both wildcards and substring (freetext) '
.
'matches.'
,
type
=>
's'
,
choices
=>
[
'off'
,
'wildcard'
,
'search'
],
default
=>
'off'
},
{
name
=>
'maxusermatches'
,
desc
=>
'Search for no more than this many matches. <br>'
.
'If set to "1", no users will be displayed on ambiguous matches. '
.
'This is useful for user privacy purposes. <br>'
.
'A value of zero means no limit.'
,
type
=>
't'
,
default
=>
'1000'
,
checker
=>
\&
check_numeric
},
{
name
=>
'confirmuniqueusermatch'
,
desc
=>
'Whether a confirmation screen should be displayed when only '
.
'one user matches a search entry'
,
type
=>
'b'
,
default
=>
1
,
},
);
1
;
...
...
post_bug.cgi
View file @
7d1af605
...
...
@@ -29,6 +29,8 @@ use lib qw(.);
require
"CGI.pl"
;
require
"bug_form.pl"
;
use
Bugzilla::
User
;
# Shut up misguided -w warnings about "used only once". For some reason,
# "use vars" chokes on me when I try it here.
sub
sillyness
{
...
...
@@ -51,6 +53,12 @@ use vars qw($vars $template);
ConnectToDatabase
();
my
$whoid
=
confirm_login
();
# do a match on the fields if applicable
&
Bugzilla::User::
match_field
({
'cc'
=>
{
'type'
=>
'multi'
},
'assigned_to'
=>
{
'type'
=>
'single'
},
});
# The format of the initial comment can be structured by adding fields to the
# enter_bug template and then referencing them in the comment template.
...
...
process_bug.cgi
View file @
7d1af605
...
...
@@ -34,6 +34,8 @@ use lib qw(.);
require
"CGI.pl"
;
require
"bug_form.pl"
;
use
Bugzilla::
User
;
use
RelationSet
;
# Use the Flag module to modify flag data if the user set flags.
...
...
@@ -86,6 +88,14 @@ if (defined $::FORM{'id'}) {
# Make sure there are bugs to process.
scalar
(
@idlist
)
||
ThrowUserError
(
"no_bugs_chosen"
);
# do a match on the fields if applicable
&
Bugzilla::User::
match_field
({
'qa_contact'
=>
{
'type'
=>
'single'
},
'newcc'
=>
{
'type'
=>
'multi'
},
'assigned_to'
=>
{
'type'
=>
'single'
},
});
# If we are duping bugs, let's also make sure that we can change
# the original. This takes care of issue A on bug 96085.
if
(
defined
$::FORM
{
'dup_id'
}
&&
$::FORM
{
'knob'
}
eq
"duplicate"
)
{
...
...
template/en/default/global/code-error.html.tmpl
View file @
7d1af605
...
...
@@ -90,6 +90,10 @@
Attempted to add bug to an inactive group, identified by the bit
'[% bit FILTER html %]'.
[% ELSIF error == "bad_arg" %]
Bad argument <code>[% argument %]</code> sent to
<code>[% function %]</code> function.
[% ELSIF error == "invalid_attach_id_to_obsolete" %]
The attachment number of one of the attachments you wanted to obsolete,
[% attach_id FILTER html %], is invalid.
...
...
template/en/default/global/field-descs.html.tmpl
View file @
7d1af605
...
...
@@ -28,6 +28,7 @@
"bug_id" => "Bug ID",
"bug_severity" => "Severity",
"bug_status" => "Status",
"cc" => "CC",
"cclist_accessible" => "CC list accessible?",
"component_id" => "Component ID",
"component" => "Component",
...
...
@@ -37,6 +38,7 @@
"everconfirmed" => "Ever confirmed?",
"groupset" => "Groupset",
"keywords" => "Keywords",
"newcc" => "CC",
"op_sys" => "OS",
"percentage_complete" => "%Complete",
"priority" => "Priority",
...
...
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