Bug 174039: Set flags on bug entry - Patch by Frédéric Buclin <LpSolit@gmail.com> r=wurblzap r=myk a=myk
git-svn-id: svn://10.0.0.236/trunk@203576 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
@@ -51,7 +51,8 @@ use Bugzilla::Constants;
|
||||
use Bugzilla::Error;
|
||||
use Bugzilla::Flag;
|
||||
use Bugzilla::User;
|
||||
use Bugzilla::Util qw(trick_taint);
|
||||
use Bugzilla::Util;
|
||||
use Bugzilla::Field;
|
||||
|
||||
sub get {
|
||||
my $invocant = shift;
|
||||
@@ -594,12 +595,89 @@ sub validate_content_type {
|
||||
|
||||
=pod
|
||||
|
||||
=item C<insert_attachment_for_bug($throw_error, $bug_id, $user, $timestamp, $hr_vars)>
|
||||
=item C<validate_can_edit()>
|
||||
|
||||
Description: validates if the user is allowed to edit the attachment.
|
||||
Only the submitter or someone with editbugs privs can edit it.
|
||||
|
||||
Returns: 1 on success. Else an error is thrown.
|
||||
|
||||
=cut
|
||||
|
||||
sub validate_can_edit {
|
||||
my ($class, $attach_id) = @_;
|
||||
my $dbh = Bugzilla->dbh;
|
||||
my $user = Bugzilla->user;
|
||||
|
||||
# People in editbugs can edit all attachments
|
||||
return if $user->in_group('editbugs');
|
||||
|
||||
# Bug 97729 - the submitter can edit their attachments
|
||||
my ($ref) = $dbh->selectrow_array('SELECT attach_id FROM attachments
|
||||
WHERE attach_id = ? AND submitter_id = ?',
|
||||
undef, ($attach_id, $user->id));
|
||||
|
||||
$ref || ThrowUserError('illegal_attachment_edit', { attach_id => $attach_id });
|
||||
}
|
||||
|
||||
=item C<validate_obsolete($bug_id)>
|
||||
|
||||
Description: validates if attachments the user wants to mark as obsolete
|
||||
really belong to the given bug and are not already obsolete.
|
||||
|
||||
Params: $bug_id - The bug ID obsolete attachments should belong to.
|
||||
|
||||
Returns: 1 on success. Else an error is thrown.
|
||||
|
||||
=cut
|
||||
|
||||
sub validate_obsolete {
|
||||
my ($class, $bug_id) = @_;
|
||||
my $cgi = Bugzilla->cgi;
|
||||
|
||||
# Make sure the attachment id is valid and the user has permissions to view
|
||||
# the bug to which it is attached.
|
||||
my @obsolete_attachments;
|
||||
foreach my $attachid ($cgi->param('obsolete')) {
|
||||
my $vars = {};
|
||||
$vars->{'attach_id'} = $attachid;
|
||||
|
||||
detaint_natural($attachid)
|
||||
|| ThrowCodeError('invalid_attach_id_to_obsolete', $vars);
|
||||
|
||||
my $attachment = Bugzilla::Attachment->get($attachid);
|
||||
|
||||
# Make sure the attachment exists in the database.
|
||||
ThrowUserError('invalid_attach_id', $vars) unless $attachment;
|
||||
|
||||
$vars->{'description'} = $attachment->description;
|
||||
|
||||
if ($attachment->bug_id != $bug_id) {
|
||||
$vars->{'my_bug_id'} = $bug_id;
|
||||
$vars->{'attach_bug_id'} = $attachment->bug_id;
|
||||
ThrowCodeError('mismatched_bug_ids_on_obsolete', $vars);
|
||||
}
|
||||
|
||||
if ($attachment->isobsolete) {
|
||||
ThrowCodeError('attachment_already_obsolete', $vars);
|
||||
}
|
||||
|
||||
# Check that the user can modify this attachment.
|
||||
$class->validate_can_edit($attachid);
|
||||
push(@obsolete_attachments, $attachment);
|
||||
}
|
||||
return @obsolete_attachments;
|
||||
}
|
||||
|
||||
|
||||
=pod
|
||||
|
||||
=item C<insert_attachment_for_bug($throw_error, $bug, $user, $timestamp, $hr_vars)>
|
||||
|
||||
Description: inserts an attachment from CGI input for the given bug.
|
||||
|
||||
Params: C<$bug_id> - integer - the ID of the bug for which
|
||||
to insert the attachment.
|
||||
Params: C<$bug> - Bugzilla::Bug object - the bug for which to insert
|
||||
the attachment.
|
||||
C<$user> - Bugzilla::User object - the user we're inserting an
|
||||
attachment for.
|
||||
C<$timestamp> - scalar - timestamp of the insert as returned
|
||||
@@ -614,7 +692,7 @@ Returns: the ID of the new attachment.
|
||||
=cut
|
||||
|
||||
sub insert_attachment_for_bug {
|
||||
my ($class, $throw_error, $bug_id, $user, $timestamp, $hr_vars) = @_;
|
||||
my ($class, $throw_error, $bug, $user, $timestamp, $hr_vars) = @_;
|
||||
|
||||
my $cgi = Bugzilla->cgi;
|
||||
my $dbh = Bugzilla->dbh;
|
||||
@@ -671,8 +749,8 @@ sub insert_attachment_for_bug {
|
||||
# Setting the third param to -1 will force this function to check this
|
||||
# point.
|
||||
# XXX needs $throw_error treatment
|
||||
Bugzilla::Flag::validate($cgi, $bug_id, -1);
|
||||
Bugzilla::FlagType::validate($cgi, $bug_id, -1);
|
||||
Bugzilla::Flag::validate($cgi, $bug->bug_id, -1);
|
||||
Bugzilla::FlagType::validate($cgi, $bug->bug_id, -1);
|
||||
|
||||
# Escape characters in strings that will be used in SQL statements.
|
||||
my $description = $cgi->param('description');
|
||||
@@ -684,7 +762,7 @@ sub insert_attachment_for_bug {
|
||||
"INSERT INTO attachments
|
||||
(bug_id, creation_ts, filename, description,
|
||||
mimetype, ispatch, isurl, isprivate, submitter_id)
|
||||
VALUES (?,?,?,?,?,?,?,?,?)", undef, ($bug_id, $timestamp, $filename,
|
||||
VALUES (?,?,?,?,?,?,?,?,?)", undef, ($bug->bug_id, $timestamp, $filename,
|
||||
$description, $contenttype, $cgi->param('ispatch'),
|
||||
$isurl, $isprivate, $user->id));
|
||||
# Retrieve the ID of the newly created attachment record.
|
||||
@@ -724,6 +802,36 @@ sub insert_attachment_for_bug {
|
||||
close AH;
|
||||
close $fh;
|
||||
}
|
||||
|
||||
# Now handle flags.
|
||||
my @obsolete_attachments;
|
||||
if ($cgi->param('obsolete')) {
|
||||
@obsolete_attachments = $class->validate_obsolete($bug->bug_id);
|
||||
}
|
||||
|
||||
# Make existing attachments obsolete.
|
||||
my $fieldid = get_field_id('attachments.isobsolete');
|
||||
|
||||
foreach my $obsolete_attachment (@obsolete_attachments) {
|
||||
# If the obsolete attachment has request flags, cancel them.
|
||||
# This call must be done before updating the 'attachments' table.
|
||||
Bugzilla::Flag::CancelRequests($bug, $obsolete_attachment, $timestamp);
|
||||
|
||||
$dbh->do('UPDATE attachments SET isobsolete = 1 WHERE attach_id = ?',
|
||||
undef, $obsolete_attachment->id);
|
||||
|
||||
$dbh->do('INSERT INTO bugs_activity (bug_id, attach_id, who, bug_when,
|
||||
fieldid, removed, added)
|
||||
VALUES (?,?,?,?,?,?,?)',
|
||||
undef, ($bug->bug_id, $obsolete_attachment->id, $user->id,
|
||||
$timestamp, $fieldid, 0, 1));
|
||||
}
|
||||
|
||||
# Create flags.
|
||||
my $attachment = Bugzilla::Attachment->get($attachid);
|
||||
Bugzilla::Flag::process($bug, $attachment, $timestamp, $cgi);
|
||||
|
||||
# Return the ID of the new attachment.
|
||||
return $attachid;
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
# The Original Code is the Bugzilla Bug Tracking System.
|
||||
#
|
||||
# Contributor(s): Tiago R. Mello <timello@async.com.br>
|
||||
#
|
||||
# Frédéric Buclin <LpSolit@gmail.com>
|
||||
|
||||
use strict;
|
||||
|
||||
@@ -22,6 +22,7 @@ package Bugzilla::Component;
|
||||
use Bugzilla::Util;
|
||||
use Bugzilla::Error;
|
||||
use Bugzilla::User;
|
||||
use Bugzilla::FlagType;
|
||||
|
||||
###############################
|
||||
#### Initialization ####
|
||||
@@ -135,6 +136,24 @@ sub default_qa_contact {
|
||||
return $self->{'default_qa_contact'};
|
||||
}
|
||||
|
||||
sub flag_types {
|
||||
my $self = shift;
|
||||
|
||||
if (!defined $self->{'flag_types'}) {
|
||||
$self->{'flag_types'} = {};
|
||||
$self->{'flag_types'}->{'bug'} =
|
||||
Bugzilla::FlagType::match({ 'target_type' => 'bug',
|
||||
'product_id' => $self->product_id,
|
||||
'component_id' => $self->id });
|
||||
|
||||
$self->{'flag_types'}->{'attachment'} =
|
||||
Bugzilla::FlagType::match({ 'target_type' => 'attachment',
|
||||
'product_id' => $self->product_id,
|
||||
'component_id' => $self->id });
|
||||
}
|
||||
return $self->{'flag_types'};
|
||||
}
|
||||
|
||||
###############################
|
||||
#### Accessors ####
|
||||
###############################
|
||||
@@ -193,6 +212,8 @@ Bugzilla::Component - Bugzilla product component class.
|
||||
my $product_id = $component->product_id;
|
||||
my $default_assignee = $component->default_assignee;
|
||||
my $default_qa_contact = $component->default_qa_contact;
|
||||
my $bug_flag_types = $component->flag_types->{'bug'};
|
||||
my $attach_flag_types = $component->flag_types->{'attachment'};
|
||||
|
||||
my $component = Bugzilla::Component::check_component($product, 'AcmeComp');
|
||||
|
||||
@@ -252,6 +273,15 @@ Component.pm represents a Product Component object.
|
||||
|
||||
Returns: A Bugzilla::User object.
|
||||
|
||||
=item C<flag_types()>
|
||||
|
||||
Description: Returns all bug and attachment flagtypes available for
|
||||
the component.
|
||||
|
||||
Params: none.
|
||||
|
||||
Returns: Two references to an array of flagtype objects.
|
||||
|
||||
=back
|
||||
|
||||
=head1 SUBROUTINES
|
||||
|
||||
@@ -78,7 +78,7 @@ sub _throw_error {
|
||||
my $message;
|
||||
$template->process($name, $vars, \$message)
|
||||
|| ThrowTemplateError($template->error());
|
||||
die("$message");
|
||||
die("$message\n");
|
||||
} else {
|
||||
print Bugzilla->cgi->header();
|
||||
$template->process($name, $vars)
|
||||
|
||||
@@ -177,6 +177,24 @@ sub user_has_access {
|
||||
undef, $self->id);
|
||||
}
|
||||
|
||||
sub flag_types {
|
||||
my $self = shift;
|
||||
|
||||
if (!defined $self->{'flag_types'}) {
|
||||
$self->{'flag_types'} = {};
|
||||
foreach my $type ('bug', 'attachment') {
|
||||
my %flagtypes;
|
||||
foreach my $component (@{$self->components}) {
|
||||
foreach my $flagtype (@{$component->flag_types->{$type}}) {
|
||||
$flagtypes{$flagtype->{'id'}} ||= $flagtype;
|
||||
}
|
||||
}
|
||||
$self->{'flag_types'}->{$type} = [sort { $a->{'sortkey'} <=> $b->{'sortkey'}
|
||||
|| $a->{'name'} cmp $b->{'name'} } values %flagtypes];
|
||||
}
|
||||
}
|
||||
return $self->{'flag_types'};
|
||||
}
|
||||
|
||||
###############################
|
||||
#### Accessors ######
|
||||
@@ -231,6 +249,7 @@ Bugzilla::Product - Bugzilla product class.
|
||||
my $bugcount = $product->bug_count();
|
||||
my $bug_ids = $product->bug_ids();
|
||||
my $has_access = $product->user_has_access($user);
|
||||
my $flag_types = $product->flag_types();
|
||||
|
||||
my $id = $product->id;
|
||||
my $name = $product->name;
|
||||
@@ -320,6 +339,15 @@ below.
|
||||
Returns C<1> If this user's groups allow him C<entry> access to
|
||||
this Product, C<0> otherwise.
|
||||
|
||||
=item C<flag_types()>
|
||||
|
||||
Description: Returns flag types available for at least one of
|
||||
its components.
|
||||
|
||||
Params: none.
|
||||
|
||||
Returns: Two references to an array of flagtype objects.
|
||||
|
||||
=back
|
||||
|
||||
=head1 SUBROUTINES
|
||||
|
||||
@@ -206,24 +206,6 @@ sub validateContext
|
||||
return $context;
|
||||
}
|
||||
|
||||
sub validateCanEdit
|
||||
{
|
||||
my ($attach_id) = (@_);
|
||||
my $dbh = Bugzilla->dbh;
|
||||
|
||||
# People in editbugs can edit all attachments
|
||||
return if UserInGroup("editbugs");
|
||||
|
||||
# Bug 97729 - the submitter can edit their attachments
|
||||
my ($ref) = $dbh->selectrow_array("SELECT attach_id FROM attachments
|
||||
WHERE attach_id = ?
|
||||
AND submitter_id = ?",
|
||||
undef, ($attach_id, Bugzilla->user->id));
|
||||
|
||||
|
||||
$ref || ThrowUserError("illegal_attachment_edit",{ attach_id => $attach_id });
|
||||
}
|
||||
|
||||
sub validateCanChangeAttachment
|
||||
{
|
||||
my ($attachid) = @_;
|
||||
@@ -270,41 +252,6 @@ sub validatePrivate
|
||||
$cgi->param('isprivate', $cgi->param('isprivate') ? 1 : 0);
|
||||
}
|
||||
|
||||
sub validateObsolete {
|
||||
# Make sure the attachment id is valid and the user has permissions to view
|
||||
# the bug to which it is attached.
|
||||
my @obsolete_attachments;
|
||||
foreach my $attachid ($cgi->param('obsolete')) {
|
||||
my $vars = {};
|
||||
$vars->{'attach_id'} = $attachid;
|
||||
|
||||
detaint_natural($attachid)
|
||||
|| ThrowCodeError("invalid_attach_id_to_obsolete", $vars);
|
||||
|
||||
my $attachment = Bugzilla::Attachment->get($attachid);
|
||||
|
||||
# Make sure the attachment exists in the database.
|
||||
ThrowUserError("invalid_attach_id", $vars) unless $attachment;
|
||||
|
||||
$vars->{'description'} = $attachment->description;
|
||||
|
||||
if ($attachment->bug_id != $cgi->param('bugid')) {
|
||||
$vars->{'my_bug_id'} = $cgi->param('bugid');
|
||||
$vars->{'attach_bug_id'} = $attachment->bug_id;
|
||||
ThrowCodeError("mismatched_bug_ids_on_obsolete", $vars);
|
||||
}
|
||||
|
||||
if ($attachment->isobsolete) {
|
||||
ThrowCodeError("attachment_already_obsolete", $vars);
|
||||
}
|
||||
|
||||
# Check that the user can modify this attachment
|
||||
validateCanEdit($attachid);
|
||||
push(@obsolete_attachments, $attachment);
|
||||
}
|
||||
return @obsolete_attachments;
|
||||
}
|
||||
|
||||
# Returns 1 if the parameter is a content-type viewable in this browser
|
||||
# Note that we don't use $cgi->Accept()'s ability to check if a content-type
|
||||
# matches, because this will return a value even if it's matched by the generic
|
||||
@@ -789,38 +736,19 @@ sub insert
|
||||
ValidateComment(scalar $cgi->param('comment'));
|
||||
my ($timestamp) = Bugzilla->dbh->selectrow_array("SELECT NOW()");
|
||||
|
||||
my $bug = new Bugzilla::Bug($bugid, $user->id);
|
||||
my $attachid =
|
||||
Bugzilla::Attachment->insert_attachment_for_bug(THROW_ERROR,
|
||||
$bugid, $user,
|
||||
Bugzilla::Attachment->insert_attachment_for_bug(THROW_ERROR, $bug, $user,
|
||||
$timestamp, \$vars);
|
||||
my $isprivate = $cgi->param('isprivate') ? 1 : 0;
|
||||
my @obsolete_attachments;
|
||||
@obsolete_attachments = validateObsolete() if $cgi->param('obsolete');
|
||||
|
||||
# Insert a comment about the new attachment into the database.
|
||||
my $comment = "Created an attachment (id=$attachid)\n" .
|
||||
$cgi->param('description') . "\n";
|
||||
$comment .= ("\n" . $cgi->param('comment')) if defined $cgi->param('comment');
|
||||
|
||||
my $isprivate = $cgi->param('isprivate') ? 1 : 0;
|
||||
AppendComment($bugid, $user->id, $comment, $isprivate, $timestamp);
|
||||
|
||||
# Make existing attachments obsolete.
|
||||
my $fieldid = get_field_id('attachments.isobsolete');
|
||||
my $bug = new Bugzilla::Bug($bugid, $user->id);
|
||||
|
||||
foreach my $obsolete_attachment (@obsolete_attachments) {
|
||||
# If the obsolete attachment has request flags, cancel them.
|
||||
# This call must be done before updating the 'attachments' table.
|
||||
Bugzilla::Flag::CancelRequests($bug, $obsolete_attachment, $timestamp);
|
||||
|
||||
$dbh->do("UPDATE attachments SET isobsolete = 1 " .
|
||||
"WHERE attach_id = ?", undef, $obsolete_attachment->id);
|
||||
$dbh->do("INSERT INTO bugs_activity (bug_id, attach_id, who, bug_when,
|
||||
fieldid, removed, added)
|
||||
VALUES (?,?,?,?,?,?,?)", undef,
|
||||
$bugid, $obsolete_attachment->id, $user->id, $timestamp, $fieldid, 0, 1);
|
||||
}
|
||||
|
||||
# Assign the bug to the user, if they are allowed to take it
|
||||
my $owner = "";
|
||||
|
||||
@@ -862,13 +790,7 @@ sub insert
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Create flags.
|
||||
# Update the bug object with updated data.
|
||||
$bug = new Bugzilla::Bug($bugid, $user->id);
|
||||
my $attachment = Bugzilla::Attachment->get($attachid);
|
||||
Bugzilla::Flag::process($bug, $attachment, $timestamp, $cgi);
|
||||
|
||||
|
||||
# Define the variables and functions that will be passed to the UI template.
|
||||
$vars->{'mailrecipients'} = { 'changer' => $user->login,
|
||||
'owner' => $owner };
|
||||
@@ -947,7 +869,7 @@ sub update
|
||||
# Retrieve and validate parameters
|
||||
ValidateComment(scalar $cgi->param('comment'));
|
||||
my ($attach_id, $bugid) = validateID();
|
||||
validateCanEdit($attach_id);
|
||||
Bugzilla::Attachment->validate_can_edit($attach_id);
|
||||
validateCanChangeAttachment($attach_id);
|
||||
Bugzilla::Attachment->validate_description(THROW_ERROR);
|
||||
Bugzilla::Attachment->validate_is_patch(THROW_ERROR);
|
||||
@@ -1113,7 +1035,7 @@ sub delete_attachment {
|
||||
|
||||
# Make sure the administrator is allowed to edit this attachment.
|
||||
my ($attach_id, $bug_id) = validateID();
|
||||
validateCanEdit($attach_id);
|
||||
Bugzilla::Attachment->validate_can_edit($attach_id);
|
||||
validateCanChangeAttachment($attach_id);
|
||||
|
||||
my $attachment = Bugzilla::Attachment->get($attach_id);
|
||||
|
||||
@@ -536,11 +536,13 @@ $dbh->do("UPDATE bugs SET creation_ts = ? WHERE bug_id = ?",
|
||||
|
||||
$dbh->bz_unlock_tables();
|
||||
|
||||
my $bug = new Bugzilla::Bug($id, $user->id);
|
||||
|
||||
# Add an attachment if requested.
|
||||
if (defined($cgi->upload('data')) || $cgi->param('attachurl')) {
|
||||
$cgi->param('isprivate', $cgi->param('commentprivacy'));
|
||||
Bugzilla::Attachment->insert_attachment_for_bug(!THROW_ERROR,
|
||||
$id, $user, $timestamp,
|
||||
$bug, $user, $timestamp,
|
||||
\$vars)
|
||||
|| ($vars->{'message'} = 'attachment_creation_failed');
|
||||
|
||||
@@ -551,11 +553,30 @@ if (defined($cgi->upload('data')) || $cgi->param('attachurl')) {
|
||||
};
|
||||
}
|
||||
|
||||
# Add flags, if any. To avoid dying if something goes wrong
|
||||
# while processing flags, we will eval() flag validation.
|
||||
# This requires to be in batch mode.
|
||||
# XXX: this can go away as soon as flag validation is able to
|
||||
# fail without dying.
|
||||
Bugzilla->batch(1);
|
||||
eval {
|
||||
# Make sure no flags have already been set for this bug.
|
||||
# Impossible? - Well, depends if you hack the URL or not.
|
||||
# Passing a bug ID of 0 will make it complain if it finds one.
|
||||
Bugzilla::Flag::validate($cgi, 0);
|
||||
Bugzilla::FlagType::validate($cgi, $id);
|
||||
Bugzilla::Flag::process($bug, undef, $timestamp, $cgi);
|
||||
};
|
||||
Bugzilla->batch(0);
|
||||
if ($@) {
|
||||
$vars->{'message'} = 'flag_creation_failed';
|
||||
$vars->{'flag_creation_error'} = $@;
|
||||
}
|
||||
|
||||
# Email everyone the details of the new bug
|
||||
$vars->{'mailrecipients'} = {'changer' => $user->login};
|
||||
|
||||
$vars->{'id'} = $id;
|
||||
my $bug = new Bugzilla::Bug($id, $user->id);
|
||||
$vars->{'bug'} = $bug;
|
||||
|
||||
ThrowCodeError("bug_error", { bug => $bug }) if $bug->error;
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
var initialowners = new Array([% product.components.size %]);
|
||||
var last_initialowner;
|
||||
var components = new Array([% product.components.size %]);
|
||||
var flags = new Array([% product.components.size %]);
|
||||
[% IF Param("useqacontact") %]
|
||||
var initialqacontacts = new Array([% product.components.size %]);
|
||||
var last_initialqacontact;
|
||||
@@ -45,6 +46,17 @@ var components = new Array([% product.components.size %]);
|
||||
[%- FOREACH c = product.components %]
|
||||
components[[% count %]] = "[% c.name FILTER js %]";
|
||||
initialowners[[% count %]] = "[% c.default_assignee.login FILTER js %]";
|
||||
var flag_list = new Array([% c.flag_types.bug.size + c.flag_types.attachment.size %]);
|
||||
[% flag_count = 0 %]
|
||||
[% FOREACH f = c.flag_types.bug %]
|
||||
flag_list[[% flag_count %]] = "[% f.id %]";
|
||||
[% flag_count = flag_count + 1 %]
|
||||
[% END %]
|
||||
[% FOREACH f = c.flag_types.attachment %]
|
||||
flag_list[[% flag_count %]] = "[% f.id %]";
|
||||
[% flag_count = flag_count + 1 %]
|
||||
[% END %]
|
||||
flags[[% count %]] = flag_list;
|
||||
[% IF Param("useqacontact") %]
|
||||
initialqacontacts[[% count %]] = "[% c.default_qa_contact.login FILTER js %]";
|
||||
[% END %]
|
||||
@@ -53,8 +65,8 @@ var components = new Array([% product.components.size %]);
|
||||
|
||||
function set_assign_to() {
|
||||
// Based on the selected component, fill the "Assign To:" field
|
||||
// with the default component owner, and the the "QA Contact:" field
|
||||
// with the default QA Contact.
|
||||
// with the default component owner, and the "QA Contact:" field
|
||||
// with the default QA Contact. It also selectively enables flags.
|
||||
var form = document.Create;
|
||||
var assigned_to = form.assigned_to.value;
|
||||
|
||||
@@ -87,6 +99,31 @@ function set_assign_to() {
|
||||
last_initialqacontact = contact;
|
||||
}
|
||||
[% END %]
|
||||
|
||||
// First, we disable all flags. Then we re-enable those
|
||||
// which are available for the selected component.
|
||||
var inputElements = document.getElementsByTagName("select");
|
||||
var inputElement, flagField;
|
||||
for ( var i=0 ; i<inputElements.length ; i++ ) {
|
||||
inputElement = inputElements.item(i);
|
||||
if (inputElement.name.search(/^flag_type-(\d+)$/) != -1) {
|
||||
var id = inputElement.name.replace(/^flag_type-(\d+)$/, "$1");
|
||||
inputElement.disabled = true;
|
||||
// Also disable the requestee field, if it exists.
|
||||
inputElement = document.getElementById("requestee_type-" + id);
|
||||
if (inputElement) inputElement.disabled = true;
|
||||
}
|
||||
}
|
||||
// Now enable flags available for the selected component.
|
||||
for (var i = 0; i < flags[index].length; i++) {
|
||||
flagField = document.getElementById("flag_type-" + flags[index][i]);
|
||||
if (flagField) {
|
||||
flagField.disabled = false;
|
||||
// Re-enabling the requestee field depends on the status
|
||||
// of the flag.
|
||||
toggleRequesteeField(flagField, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -113,11 +150,7 @@ function handleWantsAttachment(wants_attachment) {
|
||||
<table cellspacing="2" cellpadding="0" border="0">
|
||||
|
||||
<tr>
|
||||
<td><br></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td></td>
|
||||
<td> </td>
|
||||
<td colspan="3">
|
||||
[%# Migration note: The following file corresponds to the old Param
|
||||
# 'entryheaderhtml'
|
||||
@@ -127,7 +160,8 @@ function handleWantsAttachment(wants_attachment) {
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><br></td>
|
||||
<td> </td>
|
||||
<td colspan="3"> </td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
@@ -173,7 +207,7 @@ function handleWantsAttachment(wants_attachment) {
|
||||
|
||||
<tr>
|
||||
<td> </td>
|
||||
<td colspan="3"></td>
|
||||
<td colspan="3"> </td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
@@ -185,29 +219,30 @@ function handleWantsAttachment(wants_attachment) {
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
[% IF Param('letsubmitterchoosepriority') %]
|
||||
[% sel = { description => 'Priority', name => 'priority' } %]
|
||||
[% INCLUDE select %]
|
||||
[% ELSE %]
|
||||
<input type="hidden" name="priority"
|
||||
value="[% default.priority FILTER html %]">
|
||||
[% END %]
|
||||
[% IF Param('letsubmitterchoosepriority') %]
|
||||
[% sel = { description => 'Priority', name => 'priority' } %]
|
||||
[% INCLUDE select %]
|
||||
[% ELSE %]
|
||||
<td colspan="2">
|
||||
<input type="hidden" name="priority" value="[% default.priority FILTER html %]">
|
||||
</td>
|
||||
[% END %]
|
||||
|
||||
[% sel = { description => 'Severity', name => 'bug_severity' } %]
|
||||
[% INCLUDE select %]
|
||||
[% sel = { description => 'Severity', name => 'bug_severity' } %]
|
||||
[% INCLUDE select %]
|
||||
</tr>
|
||||
|
||||
[% IF Param('usetargetmilestone') && Param('letsubmitterchoosemilestone') %]
|
||||
<tr>
|
||||
[% sel = { description => 'Target Milestone', name => 'target_milestone' } %]
|
||||
[% INCLUDE select %]
|
||||
<td colspan="2"></td>
|
||||
[% sel = { description => 'Target Milestone', name => 'target_milestone' } %]
|
||||
[% INCLUDE select %]
|
||||
<td colspan="2"> </td>
|
||||
</tr>
|
||||
[% END %]
|
||||
|
||||
<tr>
|
||||
<td> </td>
|
||||
<td colspan="3"></td>
|
||||
<td colspan="3"> </td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
@@ -220,7 +255,19 @@ function handleWantsAttachment(wants_attachment) {
|
||||
[% sel = { description => 'Initial State', name => 'bug_status' } %]
|
||||
[% INCLUDE select %]
|
||||
[% END %]
|
||||
<td colspan="2"></td>
|
||||
<td> </td>
|
||||
[%# Calculate the number of rows we can use for flags %]
|
||||
[% num_rows = 6 + (Param("useqacontact") ? 1 : 0) +
|
||||
(UserInGroup(Param('timetrackinggroup')) ? 3 : 0) +
|
||||
(Param("usebugaliases") ? 1 : 0)
|
||||
%]
|
||||
<td rowspan="[% num_rows FILTER html %]" valign="top">
|
||||
[% IF product.flag_types.bug.size > 0 %]
|
||||
[% PROCESS "flag/list.html.tmpl" flag_types = product.flag_types.bug
|
||||
any_flags_requesteeble = 1
|
||||
%]
|
||||
[% END %]
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
@@ -229,7 +276,7 @@ function handleWantsAttachment(wants_attachment) {
|
||||
<a href="page.cgi?id=fields.html#assigned_to">Assign To</a>:
|
||||
</strong>
|
||||
</td>
|
||||
<td colspan="3">
|
||||
<td colspan="2">
|
||||
[% INCLUDE global/userselect.html.tmpl
|
||||
name => "assigned_to"
|
||||
value => assigned_to
|
||||
@@ -244,7 +291,7 @@ function handleWantsAttachment(wants_attachment) {
|
||||
[% IF Param("useqacontact") %]
|
||||
<tr>
|
||||
<td align="right"><strong>QA Contact:</strong></td>
|
||||
<td colspan="3">
|
||||
<td colspan="2">
|
||||
[% INCLUDE global/userselect.html.tmpl
|
||||
name => "qa_contact"
|
||||
value => qa_contact
|
||||
@@ -259,7 +306,7 @@ function handleWantsAttachment(wants_attachment) {
|
||||
|
||||
<tr>
|
||||
<td align="right"><strong>Cc:</strong></td>
|
||||
<td colspan="3">
|
||||
<td colspan="2">
|
||||
[% INCLUDE global/userselect.html.tmpl
|
||||
name => "cc"
|
||||
value => cc
|
||||
@@ -272,19 +319,19 @@ function handleWantsAttachment(wants_attachment) {
|
||||
|
||||
<tr>
|
||||
<td> </td>
|
||||
<td colspan="3"></td>
|
||||
<td colspan="2"></td>
|
||||
</tr>
|
||||
|
||||
[% IF UserInGroup(Param('timetrackinggroup')) %]
|
||||
<tr>
|
||||
<td align="right"><strong>Estimated Hours:</strong></td>
|
||||
<td colspan="3">
|
||||
<td colspan="2">
|
||||
<input name="estimated_time" size="6" maxlength="6" value="0.0">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="right"><strong>Deadline:</strong></td>
|
||||
<td colspan="3">
|
||||
<td colspan="2">
|
||||
<input name="deadline" size="10" maxlength="10" value="[% deadline FILTER html %]">
|
||||
<small>(YYYY-MM-DD)</small>
|
||||
</td>
|
||||
@@ -292,14 +339,14 @@ function handleWantsAttachment(wants_attachment) {
|
||||
|
||||
<tr>
|
||||
<td> </td>
|
||||
<td colspan="3"></td>
|
||||
<td colspan="2"></td>
|
||||
</tr>
|
||||
[% END %]
|
||||
|
||||
[% IF Param("usebugaliases") %]
|
||||
<tr>
|
||||
<td align="right"><strong>Alias:</strong></td>
|
||||
<td colspan="3">
|
||||
<td colspan="2">
|
||||
<input name="alias" size="20">
|
||||
</td>
|
||||
</tr>
|
||||
@@ -307,7 +354,7 @@ function handleWantsAttachment(wants_attachment) {
|
||||
|
||||
<tr>
|
||||
<td align="right"><strong>URL:</strong></td>
|
||||
<td colspan="3">
|
||||
<td colspan="2">
|
||||
<input name="bug_file_loc" size="60"
|
||||
value="[% bug_file_loc FILTER html %]">
|
||||
</td>
|
||||
@@ -324,7 +371,7 @@ function handleWantsAttachment(wants_attachment) {
|
||||
|
||||
<tr>
|
||||
<td align="right"><strong>Summary:</strong></td>
|
||||
<td colspan="3">
|
||||
<td colspan="2">
|
||||
<input name="short_desc" size="60" value="[% short_desc FILTER html %]"
|
||||
maxlength="255">
|
||||
</td>
|
||||
@@ -389,7 +436,8 @@ function handleWantsAttachment(wants_attachment) {
|
||||
<fieldset>
|
||||
<legend>Add an attachment</legend>
|
||||
<table class="attachment_entry">
|
||||
[% PROCESS attachment/createformcontents.html.tmpl %]
|
||||
[% PROCESS attachment/createformcontents.html.tmpl
|
||||
flag_types = product.flag_types.attachment %]
|
||||
</table>
|
||||
</fieldset>
|
||||
<script type="text/javascript">
|
||||
|
||||
@@ -407,7 +407,9 @@
|
||||
'g.description',
|
||||
'sel.name',
|
||||
'sel.description',
|
||||
'cloned_bug_id'
|
||||
'cloned_bug_id',
|
||||
'flag_count',
|
||||
'f.id',
|
||||
],
|
||||
|
||||
'bug/create/create-guided.html.tmpl' => [
|
||||
|
||||
@@ -21,10 +21,9 @@
|
||||
|
||||
<script type="text/javascript">
|
||||
<!--
|
||||
var stored_onload = window.onload;
|
||||
// Enables or disables a requestee field depending on whether or not
|
||||
// the user is requesting the corresponding flag.
|
||||
function toggleRequesteeField(flagField)
|
||||
function toggleRequesteeField(flagField, no_focus)
|
||||
{
|
||||
// Convert the ID of the flag field into the ID of its corresponding
|
||||
// requestee field and then use the ID to get the field.
|
||||
@@ -36,7 +35,7 @@
|
||||
// of the flag field.
|
||||
if (flagField.value == "?") {
|
||||
requesteeField.disabled = false;
|
||||
requesteeField.focus();
|
||||
if (!no_focus) requesteeField.focus();
|
||||
} else
|
||||
requesteeField.disabled = true;
|
||||
}
|
||||
@@ -60,9 +59,6 @@
|
||||
inputElement.disabled = true;
|
||||
}
|
||||
}
|
||||
if (stored_onload) {
|
||||
stored_onload();
|
||||
}
|
||||
}
|
||||
window.onload = disableRequesteeFields;
|
||||
// -->
|
||||
|
||||
@@ -386,6 +386,13 @@
|
||||
[% END %]
|
||||
[% END %]
|
||||
|
||||
[%# If we are in batch mode, we want the error message to be plain text, not HTML %]
|
||||
[% USE Bugzilla %]
|
||||
[% IF Bugzilla.batch %]
|
||||
[% error_message FILTER none %]
|
||||
[% RETURN %]
|
||||
[% END %]
|
||||
|
||||
[% UNLESS header_done %]
|
||||
[% PROCESS global/header.html.tmpl %]
|
||||
[% END %]
|
||||
|
||||
@@ -163,6 +163,11 @@
|
||||
[%+ new_email FILTER html %] has been cancelled.
|
||||
Your old account settings have been reinstated.
|
||||
|
||||
[% ELSIF message_tag == "flag_creation_failed" %]
|
||||
[% title = "Flag Creation Failure" %]
|
||||
An error occured while validating flags:
|
||||
[%+ flag_creation_error FILTER none %]
|
||||
|
||||
[% ELSIF message_tag == "logged_out" %]
|
||||
[% title = "Logged Out" %]
|
||||
[% url = "index.cgi?GoAheadAndLogIn=1" %]
|
||||
|
||||
@@ -1412,6 +1412,13 @@
|
||||
[% END %]
|
||||
[% END %]
|
||||
|
||||
[%# If we are in batch mode, we want the error message to be plain text, not HTML %]
|
||||
[% USE Bugzilla %]
|
||||
[% IF Bugzilla.batch %]
|
||||
[% error_message FILTER none %]
|
||||
[% RETURN %]
|
||||
[% END %]
|
||||
|
||||
[% UNLESS header_done %]
|
||||
[% PROCESS global/header.html.tmpl %]
|
||||
[% END %]
|
||||
@@ -1438,8 +1445,7 @@
|
||||
[%# If a saved search fails, people want the ability to edit or delete it.
|
||||
# This is the best way of getting information about that possible saved
|
||||
# search from any error call location. %]
|
||||
|
||||
[% USE Bugzilla %]
|
||||
|
||||
[% namedcmd = Bugzilla.cgi.param("namedcmd") %]
|
||||
[% IF namedcmd AND error != "missing_query"
|
||||
AND error != "saved_search_used_by_whines" %]
|
||||
|
||||
Reference in New Issue
Block a user