Commit d0002e96 authored by lpsolit%gmail.com's avatar lpsolit%gmail.com

Bug 415541: Implement $bug->set_flags() and $attachment->set_flags() - Patch by…

Bug 415541: Implement $bug->set_flags() and $attachment->set_flags() - Patch by Fré©ric Buclin <LpSolit@gmail.com> a=LpSolit
parent 8b2db148
......@@ -101,7 +101,6 @@ use constant UPDATE_COLUMNS => qw(
ispatch
isprivate
mimetype
modification_time
);
use constant VALIDATORS => {
......@@ -445,9 +444,9 @@ flags that have been set on the attachment
sub flags {
my $self = shift;
return $self->{flags} if exists $self->{flags};
$self->{flags} = Bugzilla::Flag->match({ 'attach_id' => $self->id });
# Don't cache it as it must be in sync with ->flag_types.
$self->{flags} = [map { @{$_->{flags}} } @{$self->flag_types}];
return $self->{flags};
}
......@@ -471,7 +470,7 @@ sub flag_types {
component_id => $self->bug->component_id,
attach_id => $self->id };
$self->{flag_types} = Bugzilla::Flag::_flag_types($vars);
$self->{flag_types} = Bugzilla::Flag->_flag_types($vars);
return $self->{flag_types};
}
......@@ -482,10 +481,34 @@ sub flag_types {
sub set_content_type { $_[0]->set('mimetype', $_[1]); }
sub set_description { $_[0]->set('description', $_[1]); }
sub set_filename { $_[0]->set('filename', $_[1]); }
sub set_is_obsolete { $_[0]->set('isobsolete', $_[1]); }
sub set_is_patch { $_[0]->set('ispatch', $_[1]); }
sub set_is_private { $_[0]->set('isprivate', $_[1]); }
sub set_is_obsolete {
my ($self, $obsolete) = @_;
my $old = $self->isobsolete;
$self->set('isobsolete', $obsolete);
my $new = $self->isobsolete;
# If the attachment is being marked as obsolete, cancel pending requests.
if ($new && $old != $new) {
my @requests = grep { $_->status eq '?' } @{$self->flags};
return unless scalar @requests;
my %flag_ids = map { $_->id => 1 } @requests;
foreach my $flagtype (@{$self->flag_types}) {
@{$flagtype->{flags}} = grep { !$flag_ids{$_->id} } @{$flagtype->{flags}};
}
}
}
sub set_flags {
my ($self, $flags, $new_flags) = @_;
Bugzilla::Flag->set_flag($self, $_) foreach (@$flags, @$new_flags);
}
sub _check_bug {
my ($invocant, $bug) = @_;
my $user = Bugzilla->user;
......@@ -799,7 +822,7 @@ Params: takes a hashref with the following keys:
parameter has no effect.
C<mimetype> - string - a valid MIME type.
C<creation_ts> - string (optional) - timestamp of the insert
as returned by SELECT NOW().
as returned by SELECT LOCALTIMESTAMP(0).
C<ispatch> - boolean (optional, default false) - true if the
attachment is a patch.
C<isprivate> - boolean (optional, default false) - true if
......@@ -887,7 +910,7 @@ sub run_create_validators {
$params->{ispatch} = $params->{ispatch} ? 1 : 0;
$params->{filename} = $class->_check_filename($params->{filename}, $params->{isurl});
$params->{mimetype} = $class->_check_content_type($params->{mimetype});
$params->{creation_ts} ||= Bugzilla->dbh->selectrow_array('SELECT NOW()');
$params->{creation_ts} ||= Bugzilla->dbh->selectrow_array('SELECT LOCALTIMESTAMP(0)');
$params->{modification_time} = $params->{creation_ts};
$params->{submitter_id} = Bugzilla->user->id || ThrowCodeError('invalid_user');
......@@ -898,14 +921,14 @@ sub update {
my $self = shift;
my $dbh = Bugzilla->dbh;
my $user = Bugzilla->user;
my $bug = $self->bug;
my $timestamp = shift || $dbh->selectrow_array('SELECT NOW()');
$self->{modification_time} = $timestamp;
my $timestamp = shift || $dbh->selectrow_array('SELECT LOCALTIMESTAMP(0)');
my ($changes, $old_self) = $self->SUPER::update(@_);
# Ignore this change.
delete $changes->{modification_time};
my ($removed, $added) = Bugzilla::Flag->update_flags($self, $old_self, $timestamp);
if ($removed || $added) {
$changes->{'flagtypes.name'} = [$removed, $added];
}
# Record changes in the activity table.
my $sth = $dbh->prepare('INSERT INTO bugs_activity (bug_id, attach_id, who, bug_when,
......@@ -914,14 +937,17 @@ sub update {
foreach my $field (keys %$changes) {
my $change = $changes->{$field};
my $fieldid = get_field_id("attachments.$field");
$sth->execute($bug->id, $self->id, $user->id, $timestamp,
$field = "attachments.$field" unless $field eq "flagtypes.name";
my $fieldid = get_field_id($field);
$sth->execute($self->bug_id, $self->id, $user->id, $timestamp,
$fieldid, $change->[0], $change->[1]);
}
if (scalar(keys %$changes)) {
$dbh->do('UPDATE attachments SET modification_time = ? WHERE attach_id = ?',
undef, ($timestamp, $self->id));
$dbh->do('UPDATE bugs SET delta_ts = ? WHERE bug_id = ?',
undef, $timestamp, $bug->id);
undef, ($timestamp, $self->bug_id));
}
return $changes;
......
......@@ -590,7 +590,7 @@ sub run_create_validators {
# Callers cannot set Reporter, currently.
$params->{reporter} = $class->_check_reporter();
$params->{creation_ts} ||= Bugzilla->dbh->selectrow_array('SELECT NOW()');
$params->{creation_ts} ||= Bugzilla->dbh->selectrow_array('SELECT LOCALTIMESTAMP(0)');
$params->{delta_ts} = $params->{creation_ts};
if ($params->{estimated_time}) {
......@@ -646,7 +646,7 @@ sub update {
my $dbh = Bugzilla->dbh;
# XXX This is just a temporary hack until all updating happens
# inside this function.
my $delta_ts = shift || $dbh->selectrow_array("SELECT NOW()");
my $delta_ts = shift || $dbh->selectrow_array('SELECT LOCALTIMESTAMP(0)');
my ($changes, $old_bug) = $self->SUPER::update(@_);
......@@ -774,7 +774,13 @@ sub update {
$changes->{'bug_group'} = [join(', ', @removed_names),
join(', ', @added_names)];
}
# Flags
my ($removed, $added) = Bugzilla::Flag->update_flags($self, $old_bug, $delta_ts);
if ($removed || $added) {
$changes->{'flagtypes.name'} = [$removed, $added];
}
# Comments
foreach my $comment (@{$self->{added_comments} || []}) {
my $columns = join(',', keys %$comment);
......@@ -1931,6 +1937,11 @@ sub set_dup_id {
}
sub set_estimated_time { $_[0]->set('estimated_time', $_[1]); }
sub _set_everconfirmed { $_[0]->set('everconfirmed', $_[1]); }
sub set_flags {
my ($self, $flags, $new_flags) = @_;
Bugzilla::Flag->set_flag($self, $_) foreach (@$flags, @$new_flags);
}
sub set_op_sys { $_[0]->set('op_sys', $_[1]); }
sub set_platform { $_[0]->set('rep_platform', $_[1]); }
sub set_priority { $_[0]->set('priority', $_[1]); }
......@@ -2632,10 +2643,18 @@ sub flag_types {
component_id => $self->{component_id},
bug_id => $self->bug_id };
$self->{'flag_types'} = Bugzilla::Flag::_flag_types($vars);
$self->{'flag_types'} = Bugzilla::Flag->_flag_types($vars);
return $self->{'flag_types'};
}
sub flags {
my $self = shift;
# Don't cache it as it must be in sync with ->flag_types.
$self->{flags} = [map { @{$_->{flags}} } @{$self->flag_types}];
return $self->{flags};
}
sub isopened {
my $self = shift;
return is_open_state($self->{bug_status}) ? 1 : 0;
......
......@@ -377,7 +377,7 @@ Params:
=head2 flag-end_of_update
This happens at the end of L<Bugzilla::Flag/process>, after all other changes
This happens at the end of L<Bugzilla::Flag/update_flags>, after all other changes
are made to the database and after emails are sent. It gives you a before/after
snapshot of flags so you can react to specific flag changes.
This generally occurs inside a database transaction.
......@@ -389,7 +389,7 @@ Params:
=over
=item C<bug> - The changed bug object.
=item C<object> - The changed bug or attachment object.
=item C<timestamp> - The timestamp used for all updates in this transaction.
......
......@@ -469,26 +469,16 @@ sub insert {
store_in_file => scalar $cgi->param('bigfile'),
});
Bugzilla::Flag->set_flags($bug, $attachment, $timestamp, $vars);
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, modification_time = ?
WHERE attach_id = ?',
undef, ($timestamp, $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));
$obsolete_attachment->set_is_obsolete(1);
$obsolete_attachment->update($timestamp);
}
my ($flags, $new_flags) = Bugzilla::Flag->extract_flags_from_cgi(
$bug, $attachment, $vars, SKIP_REQUESTEE_ON_ERROR);
$attachment->set_flags($flags, $new_flags);
$attachment->update($timestamp);
# Insert a comment about the new attachment into the database.
my $comment = "Created an attachment (id=" . $attachment->id . ")\n" .
$attachment->description . "\n";
......@@ -627,27 +617,18 @@ sub update {
$bug->add_comment($comment, { isprivate => $attachment->isprivate });
}
# The order of these function calls is important, as Flag::validate
# assumes User::match_field has ensured that the values in the
# requestee fields are legitimate user email addresses.
Bugzilla::User::match_field($cgi, {
'^requestee(_type)?-(\d+)$' => { 'type' => 'multi' }
});
Bugzilla::Flag::validate($bug->id, $attachment->id);
my ($flags, $new_flags) = Bugzilla::Flag->extract_flags_from_cgi($bug, $attachment, $vars);
$attachment->set_flags($flags, $new_flags);
# Figure out when the changes were made.
my ($timestamp) = $dbh->selectrow_array("SELECT NOW()");
# Update flags. We have to do this before committing changes
# to attachments so that we can delete pending requests if the user
# is obsoleting this attachment without deleting any requests
# the user submits at the same time.
Bugzilla::Flag->process($bug, $attachment, $timestamp, $vars);
my $timestamp = $dbh->selectrow_array('SELECT LOCALTIMESTAMP(0)');
$attachment->update($timestamp);
my $changes = $attachment->update($timestamp);
# If there are changes, we updated delta_ts in the DB. We have to
# reflect this change in the bug object.
$bug->{delta_ts} = $timestamp if scalar(keys %$changes);
# Commit the comment, if any.
$bug->update();
$bug->update($timestamp);
# Commit the transaction now that we are finished updating the database.
$dbh->bz_commit_transaction();
......
......@@ -413,11 +413,7 @@ sub update {
WHERE flags.type_id = ?
AND i.type_id IS NULL',
undef, $id);
my $flags = Bugzilla::Flag->new_from_list($flag_ids);
foreach my $flag (@$flags) {
my $bug = new Bugzilla::Bug($flag->bug_id);
Bugzilla::Flag::clear($flag, $bug, $flag->attachment);
}
Bugzilla::Flag->force_retarget($flag_ids);
$flag_ids = $dbh->selectcol_arrayref('SELECT DISTINCT flags.id
FROM flags
......@@ -431,11 +427,7 @@ sub update {
AND (bugs.component_id = e.component_id
OR e.component_id IS NULL)',
undef, $id);
$flags = Bugzilla::Flag->new_from_list($flag_ids);
foreach my $flag (@$flags) {
my $bug = new Bugzilla::Bug($flag->bug_id);
Bugzilla::Flag::clear($flag, $bug, $flag->attachment);
}
Bugzilla::Flag->force_retarget($flag_ids);
# Now silently remove requestees from flags which are no longer
# specifically requestable.
......
......@@ -481,35 +481,36 @@ if ($action eq 'search') {
my $sth_set_bug_timestamp =
$dbh->prepare('UPDATE bugs SET delta_ts = ? WHERE bug_id = ?');
# Reference removals which need LogActivityEntry.
my $statement_flagupdate = 'UPDATE flags set requestee_id = NULL
WHERE bug_id = ?
AND attach_id %s
AND requestee_id = ?';
my $sth_flagupdate_attachment =
$dbh->prepare(sprintf($statement_flagupdate, '= ?'));
my $sth_flagupdate_bug =
$dbh->prepare(sprintf($statement_flagupdate, 'IS NULL'));
my $buglist = $dbh->selectall_arrayref('SELECT DISTINCT bug_id, attach_id
FROM flags
WHERE requestee_id = ?',
undef, $otherUserID);
foreach (@$buglist) {
my ($bug_id, $attach_id) = @$_;
my @old_summaries = Bugzilla::Flag->snapshot($bug_id, $attach_id);
if ($attach_id) {
$sth_flagupdate_attachment->execute($bug_id, $attach_id, $otherUserID);
my $sth_updateFlag = $dbh->prepare('INSERT INTO bugs_activity
(bug_id, attach_id, who, bug_when, fieldid, removed, added)
VALUES (?, ?, ?, ?, ?, ?, ?)');
# Flags
my $flag_ids =
$dbh->selectcol_arrayref('SELECT id FROM flags WHERE requestee_id = ?',
undef, $otherUserID);
my $flags = Bugzilla::Flag->new_from_list($flag_ids);
$dbh->do('UPDATE flags SET requestee_id = NULL, modification_date = ?
WHERE requestee_id = ?', undef, ($timestamp, $otherUserID));
# We want to remove the requestee but leave the requester alone,
# so we have to log these changes manually.
my %bugs;
push(@{$bugs{$_->bug_id}->{$_->attach_id || 0}}, $_) foreach @$flags;
my $fieldid = get_field_id('flagtypes.name');
foreach my $bug_id (keys %bugs) {
foreach my $attach_id (keys %{$bugs{$bug_id}}) {
my @old_summaries = Bugzilla::Flag->snapshot($bugs{$bug_id}->{$attach_id});
$_->_set_requestee() foreach @{$bugs{$bug_id}->{$attach_id}};
my @new_summaries = Bugzilla::Flag->snapshot($bugs{$bug_id}->{$attach_id});
my ($removed, $added) =
Bugzilla::Flag->update_activity(\@old_summaries, \@new_summaries);
$sth_updateFlag->execute($bug_id, $attach_id || undef, $userid,
$timestamp, $fieldid, $removed, $added);
}
else {
$sth_flagupdate_bug->execute($bug_id, $otherUserID);
}
my @new_summaries = Bugzilla::Flag->snapshot($bug_id, $attach_id);
# Let update_activity do all the dirty work, including setting
# the bug timestamp.
Bugzilla::Flag::update_activity($bug_id, $attach_id, $timestamp,
\@old_summaries, \@new_summaries);
$sth_set_bug_timestamp->execute($timestamp, $bug_id);
$updatedbugs{$bug_id} = 1;
}
......@@ -536,9 +537,8 @@ if ($action eq 'search') {
($otherUserID, $otherUserID));
# Deletions in referred tables which need LogActivityEntry.
$buglist = $dbh->selectcol_arrayref('SELECT bug_id FROM cc
WHERE who = ?',
undef, $otherUserID);
my $buglist = $dbh->selectcol_arrayref('SELECT bug_id FROM cc WHERE who = ?',
undef, $otherUserID);
$dbh->do('DELETE FROM cc WHERE who = ?', undef, $otherUserID);
foreach my $bug_id (@$buglist) {
LogActivityEntry($bug_id, 'cc', $otherUser->login, '', $userid,
......
......@@ -26,15 +26,15 @@ use Bugzilla::Util qw(diff_arrays);
# This code doesn't actually *do* anything, it's just here to show you
# how to use this hook.
my $args = Bugzilla->hook_args;
my ($bug, $timestamp, $old_flags, $new_flags) =
@$args{qw(bug timestamp old_flags new_flags)};
my ($object, $timestamp, $old_flags, $new_flags) =
@$args{qw(object timestamp old_flags new_flags)};
my ($removed, $added) = diff_arrays($old_flags, $new_flags);
my ($granted, $denied) = (0, 0);
foreach my $new_flag (@$added) {
$granted++ if $new_flag =~ /\+$/;
$denied++ if $new_flag =~ /-$/;
}
my $bug_id = $bug->id;
my $bug_id = (ref $object eq 'Bugzilla::Bug') ? $object->id : $object->bug_id;
my $result = "$granted flags were granted and $denied flags were denied"
. " on bug $bug_id at $timestamp.";
# Uncomment this line to see $result in your webserver's error log whenever
......
......@@ -104,7 +104,7 @@ if (defined $cgi->param('maketemplate')) {
umask 0;
# get current time
my $timestamp = $dbh->selectrow_array(q{SELECT NOW()});
my $timestamp = $dbh->selectrow_array('SELECT LOCALTIMESTAMP(0)');
# Group Validation
my @selected_groups;
......@@ -219,7 +219,10 @@ if (defined($cgi->upload('data')) || $cgi->param('attachurl')) {
if ($attachment) {
# Set attachment flags.
Bugzilla::Flag->set_flags($bug, $attachment, $timestamp, $vars);
my ($flags, $new_flags) = Bugzilla::Flag->extract_flags_from_cgi(
$bug, $attachment, $vars, SKIP_REQUESTEE_ON_ERROR);
$attachment->set_flags($flags, $new_flags);
$attachment->update($timestamp);
# Update the comment to include the new attachment ID.
# This string is hardcoded here because Template::quoteUrls()
......@@ -246,7 +249,10 @@ if (defined($cgi->upload('data')) || $cgi->param('attachurl')) {
}
# Set bug flags.
Bugzilla::Flag->set_flags($bug, undef, $timestamp, $vars);
my ($flags, $new_flags) = Bugzilla::Flag->extract_flags_from_cgi($bug, undef, $vars,
SKIP_REQUESTEE_ON_ERROR);
$bug->set_flags($flags, $new_flags);
$bug->update($timestamp);
# Email everyone the details of the new bug
$vars->{'mailrecipients'} = {'changer' => $user->login};
......
......@@ -143,22 +143,13 @@ if (defined $cgi->param('dontchange')) {
}
# do a match on the fields if applicable
# The order of these function calls is important, as Flag::validate
# assumes User::match_field has ensured that the values
# in the requestee fields are legitimate user email addresses.
&Bugzilla::User::match_field($cgi, {
Bugzilla::User::match_field($cgi, {
'qa_contact' => { 'type' => 'single' },
'newcc' => { 'type' => 'multi' },
'masscc' => { 'type' => 'multi' },
'assigned_to' => { 'type' => 'single' },
'^requestee(_type)?-(\d+)$' => { 'type' => 'multi' },
});
# Validate flags in all cases. validate() should not detect any
# reference to flags if $cgi->param('id') is undefined.
Bugzilla::Flag::validate($cgi->param('id'));
print $cgi->header() unless Bugzilla->usage_mode == USAGE_MODE_EMAIL;
# Check for a mid-air collision. Currently this only works when updating
......@@ -280,6 +271,12 @@ foreach my $bug (@bug_objects) {
$product_change ||= $changed;
}
# Flags should be set AFTER the bug has been moved into another product/component.
if ($cgi->param('id')) {
my ($flags, $new_flags) = Bugzilla::Flag->extract_flags_from_cgi($first_bug, undef, $vars);
$first_bug->set_flags($flags, $new_flags);
}
if ($cgi->param('id') && (defined $cgi->param('dependson')
|| defined $cgi->param('blocked')) )
{
......@@ -586,9 +583,6 @@ foreach my $bug (@bug_objects) {
CheckIfVotedConfirmed($bug->id);
}
# Set and update flags.
Bugzilla::Flag->process($bug, undef, $timestamp, $vars);
$dbh->bz_commit_transaction();
###############
......
......@@ -222,15 +222,10 @@
but you tried to flag it as obsolete while creating a new attachment to
[% terms.bug %] [%+ my_bug_id FILTER html %].
[% ELSIF error == "flags_not_available" %]
[% title = "Flag Editing not Allowed" %]
[% IF type == "b" %]
Flags cannot be set or changed when
changing several [% terms.bugs %] at once.
[% ELSE %]
References to existing flags when creating
a new attachment are invalid.
[% END %]
[% ELSIF error == "flag_unexpected_object" %]
[% title = "Object Not Recognized" %]
Flags cannot be set for objects of type [% caller FILTER html %].
They can only be set for [% terms.bugs %] and attachments.
[% ELSIF error == "flag_requestee_disabled" %]
[% title = "Flag not Requestable from Specific Person" %]
......
......@@ -568,12 +568,6 @@
<br>Alternately, if your attachment is an image, you could convert
it to a compressible format like JPG or PNG and try again.
[% ELSIF error == "flag_not_multiplicable" %]
[% docslinks = {'flags-overview.html' => 'An overview on Flags',
'flags.html' => 'Using Flags'} %]
You can't ask more than one person at a time for
<em>[% type.name FILTER html %]</em>.
[% ELSIF error == "flag_requestee_needs_privs" %]
[% title = "Flag Requestee Needs Privileges" %]
[% requestee.identity FILTER html %] does not have permission to set the
......@@ -632,6 +626,12 @@
The name <em>[% name FILTER html %]</em> must be 1-50 characters long
and must not contain any spaces or commas.
[% ELSIF error == "flag_type_not_multiplicable" %]
[% docslinks = {'flags-overview.html' => 'An overview on Flags',
'flags.html' => 'Using Flags'} %]
You cannot have several <em>[% type.name FILTER html %]</em> flags
for this [% IF attachment %] attachment [% ELSE %] [%+ terms.bug %] [% END %].
[% ELSIF error == "flag_update_denied" %]
[% title = "Flag Modification Denied" %]
[% admindocslinks = {'flags-overview.html#flags-admin' => 'Administering Flags',
......@@ -1158,9 +1158,11 @@
[% ELSIF error == "no_bugs_in_list" %]
[% title = "Delete Tag?" %]
This will remove all [% terms.bugs %] from the
[% tag FILTER html %] tag. This will delete the tag completely. Click
<em>[% name FILTER html %]</em> tag. This will delete the tag completely. Click
<a href="buglist.cgi?cmdtype=dorem&amp;remaction=forget&amp;namedcmd=
[%- tag FILTER url_quote %]">here</a> if you really want to delete it.
[%- name FILTER url_quote %]&amp;token=
[%- issue_hash_token([query_id, name]) FILTER url_quote %]">here</a>
if you really want to delete it.
[% ELSIF error == "no_bugs_to_remove" %]
[% title = "No Tag Selected" %]
......@@ -1742,6 +1744,10 @@
milestone
[% ELSIF class == "Bugzilla::Status" %]
status
[% ELSIF class == "Bugzilla::Flag" %]
flag
[% ELSIF class == "Bugzilla::FlagType" %]
flagtype
[% ELSIF class == "Bugzilla::Field" %]
field
[% ELSIF ( matches = class.match('^Bugzilla::Field::Choice::(.+)') ) %]
......
......@@ -24,28 +24,31 @@
[% bugidsummary = bug.bug_id _ ': ' _ bug.short_desc %]
[% attidsummary = attachment.id _ ': ' _ attachment.description %]
[% flagtype_name = flag ? flag.type.name : old_flag.type.name %]
[% statuses = { '+' => "granted" , '-' => 'denied' , 'X' => "canceled" ,
'?' => "asked" } %]
[% to_identity = "" %]
[% on_behalf_of = 0 %]
[% IF flag.status == '?' %]
[% action = flag.status || 'X' %]
[% IF flag && flag.status == '?' %]
[% subject_status = "requested" %]
[% IF flag.setter.id == user.id %]
[% IF flag.setter_id == user.id %]
[% to_identity = flag.requestee.identity _ " for" %]
[% ELSE %]
[% on_behalf_of = 1 %]
[% IF flag.requestee %][% to_identity = " to " _ flag.requestee.identity %][% END %]
[% END %]
[% ELSE %]
[% IF flag.requester %]
[% to_identity = flag.requester.identity _ "'s request for" %]
[% IF old_flag && old_flag.status == '?' %]
[% to_identity = old_flag.setter.identity _ "'s request for" %]
[% END %]
[% subject_status = statuses.${flag.status} %]
[% subject_status = statuses.$action %]
[% END %]
From: [% Param('mailfrom') %]
To: [% to %]
Subject: [% flag.type.name %] [%+ subject_status %]: [[% terms.Bug %] [%+ bug.bug_id %]] [% bug.short_desc %]
Subject: [% flagtype_name %] [%+ subject_status %]: [[% terms.Bug %] [%+ bug.bug_id %]] [% bug.short_desc %]
[%- IF attachment %] :
[Attachment [% attachment.id %]] [% attachment.description %][% END %]
X-Bugzilla-Type: request
......@@ -55,10 +58,10 @@ X-Bugzilla-Type: request
[%- FILTER bullet = wrap(80) -%]
[% IF on_behalf_of %]
[% user.identity %] has reassigned [% flag.setter.identity %]'s request for [% flag.type.name %]
[% user.identity %] has reassigned [% flag.setter.identity %]'s request for [% flagtype_name %]
[% to_identity %]:
[% ELSE %]
[% user.identity %] has [% statuses.${flag.status} %] [%+ to_identity %] [%+ flag.type.name %]:
[% user.identity %] has [% statuses.$action %] [%+ to_identity %] [%+ flagtype_name %]:
[% END %]
[% terms.Bug %] [%+ bugidsummary %]
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment