From cb7ddc43319c5a75c02f3623a48527b11f18594e Mon Sep 17 00:00:00 2001 From: Vitaliy Filippov Date: Mon, 28 Jul 2014 12:57:30 +0400 Subject: [PATCH] Refactor result reporting, move the rest of ORM code from process_bug.cgi to actual ORM class --- Bugzilla.pm | 48 +++- Bugzilla/Attachment.pm | 13 +- Bugzilla/Bug.pm | 228 +++++++++++++-- Bugzilla/BugMail.pm | 46 ++- Bugzilla/DB/Schema.pm | 2 - Bugzilla/Flag.pm | 10 +- Bugzilla/Product.pm | 37 +-- Bugzilla/Search.pm | 2 +- Bugzilla/Search/Saved.pm | 1 - Bugzilla/Template.pm | 2 +- Bugzilla/Util.pm | 2 +- attachment.cgi | 81 ++---- editusers.cgi | 9 +- email_in.pl | 139 ++------- enter_bug.cgi | 8 +- extensions/BmpConvert/lib/BmpConvert.pm | 3 +- extensions/custis/lib/Checkers.pm | 48 ++-- .../en/default/edit-checkers.html.tmpl | 2 +- .../en/default/failed-checkers.html.tmpl | 1 - .../hook/global/field-descs-end.none.tmpl | 6 - .../hook/global/header-aftermessage.html.tmpl | 7 - .../hook/global/user-error-errors.html.tmpl | 20 +- importxls.cgi | 182 +----------- js/bug-visibility.js | 11 +- mod_perl.pl | 4 +- post_bug.cgi | 55 +--- process_bug.cgi | 264 ++++-------------- show_bug.cgi | 27 +- skins/standard/global.css | 2 +- .../default/admin/components/list.html.tmpl | 1 + .../default/admin/products/updated.html.tmpl | 7 +- .../en/default/admin/users/edit.html.tmpl | 3 +- .../en/default/attachment/created.html.tmpl | 65 ----- .../en/default/attachment/updated.html.tmpl | 44 --- template/en/default/bug/checkaccess.html.tmpl | 4 + .../en/default/bug/create/created.html.tmpl | 59 ---- template/en/default/bug/field.html.tmpl | 5 +- template/en/default/bug/navigate.html.tmpl | 2 +- .../en/default/bug/process/bugmail.html.tmpl | 62 ---- .../en/default/bug/process/header.html.tmpl | 44 --- .../en/default/bug/process/midair.html.tmpl | 4 +- .../en/default/bug/process/results.html.tmpl | 63 ++++- .../default/bug/process/unsubscribe.html.tmpl | 9 +- .../bug/process/verify-field-values.html.tmpl | 8 +- .../bug/process/verify-flags.html.tmpl | 8 +- .../bug/process/verify-worktime.html.tmpl | 17 +- .../en/default/bug/session_result.html.tmpl | 63 ----- template/en/default/bug/show-header.html.tmpl | 36 +-- template/en/default/bug/show.html.tmpl | 39 +-- .../default/bug/votes/list-for-user.html.tmpl | 27 +- template/en/default/filterexceptions.pl | 9 - template/en/default/global/header.html.tmpl | 27 +- template/en/default/global/message.txt.tmpl | 5 +- template/en/default/global/messages.html.tmpl | 128 ++++++--- .../en/default/global/user-error.html.tmpl | 9 + userprefs.cgi | 2 +- votes.cgi | 43 +-- 57 files changed, 709 insertions(+), 1344 deletions(-) delete mode 100644 extensions/custis/template/en/default/hook/global/field-descs-end.none.tmpl delete mode 100644 extensions/custis/template/en/default/hook/global/header-aftermessage.html.tmpl delete mode 100644 template/en/default/attachment/created.html.tmpl delete mode 100644 template/en/default/attachment/updated.html.tmpl delete mode 100644 template/en/default/bug/create/created.html.tmpl delete mode 100644 template/en/default/bug/process/bugmail.html.tmpl delete mode 100644 template/en/default/bug/process/header.html.tmpl delete mode 100644 template/en/default/bug/session_result.html.tmpl diff --git a/Bugzilla.pm b/Bugzilla.pm index b921c955e..d473b8a1e 100644 --- a/Bugzilla.pm +++ b/Bugzilla.pm @@ -50,6 +50,7 @@ use File::Spec::Functions; use DateTime::TimeZone; use Date::Parse; use Safe; +use JSON; use Encode::MIME::Header (); # We want any compile errors to get to the browser, if possible. @@ -323,18 +324,32 @@ sub init_page # Subroutines and Methods ##################################################################### -sub add_mail_result +sub add_result_message { - my ($class, $send_result_item) = @_; - my $cache = $class->request_cache; - push(@{$cache->{send_mail_result}}, $send_result_item); + my $class = shift; + push @{$class->result_messages}, @_; } -sub get_mail_result +sub result_messages { my $class = shift; my $cache = $class->request_cache; - return $cache->{send_mail_result} || []; + if (!$cache->{send_mail_result}) + { + my $s = $class->session_data && $class->session_data; + $cache->{send_mail_result} = $s ? ($s->{result_messages} ||= []) : []; + } + return $cache->{send_mail_result}; +} + +sub send_mail +{ + my $class = shift; + my $cache = $class->request_cache; + for (@{$cache->{send_mail_result} || []}) + { + Bugzilla::BugMail::send_results($_); + } } sub template @@ -367,8 +382,12 @@ sub session_data my ($class, $s) = @_; my $c = $class->request_cache; $c->{session} || return undef; - $INC{'JSON.pm'} || require JSON || return undef; - my $d = $c->{session}->{session_data} ? JSON::decode_json($c->{session}->{session_data}) : {}; + if (!$c->{session}->{_session_data_decoded}) + { + $c->{session}->{_session_data_decoded} = ($c->{session}->{session_data} + ? JSON::decode_json($c->{session}->{session_data}) : {}); + } + my $d = $c->{session}->{_session_data_decoded}; if ($s && %$s) { for (keys %$s) @@ -376,17 +395,26 @@ sub session_data $d->{$_} = $s->{$_}; defined $d->{$_} or delete $d->{$_}; } - $c->{session}->{session_data} = JSON::encode_json($d); } return $d; } +sub delete_session_data +{ + my $class = shift; + $class->save_session_data({ map { ($_ => undef) } @_ }); +} + sub save_session_data { my ($class, $s) = @_; my $c = $class->request_cache; + $class->session_data({ result_messages => $class->result_messages }); $class->session_data($s) || return undef; - Bugzilla->dbh->do('UPDATE logincookies SET session_data=? WHERE cookie=?', undef, $c->{session}->{session_data}, $c->{session}->{cookie}); + Bugzilla->dbh->do( + 'UPDATE logincookies SET session_data=? WHERE cookie=?', undef, + JSON::encode_json($c->{session}->{_session_data_decoded}), $c->{session}->{cookie} + ); } our $extension_packages; diff --git a/Bugzilla/Attachment.pm b/Bugzilla/Attachment.pm index 0228ad590..f7ca26228 100644 --- a/Bugzilla/Attachment.pm +++ b/Bugzilla/Attachment.pm @@ -1131,7 +1131,7 @@ sub get_content_type # CustIS Bug 68919 - Create multiple attachments to bug sub add_multiple { - my ($bug, $cgi, $send_attrs) = @_; + my ($bug, $cgi) = @_; my $multiple = {}; my $params = $cgi->Vars; my ($multi, $key); @@ -1172,7 +1172,7 @@ sub add_multiple { if ($multiple->{$_}->{data}) { - add_attachment($bug, $multiple->{$_}, $send_attrs); + add_attachment($bug, $multiple->{$_}); } } } @@ -1180,7 +1180,7 @@ sub add_multiple # Insert a new attachment into the database. sub add_attachment { - my ($bug, $params, $send_attrs) = @_; + my ($bug, $params) = @_; my $dbh = Bugzilla->dbh; my $user = Bugzilla->user; @@ -1227,7 +1227,7 @@ sub add_attachment }); # Insert a comment about the new attachment into the database. - # TODO move comment adding into Bugzilla::Attachment + # FIXME move comment adding into Bugzilla::Attachment my $comment = defined $params->{comment} ? $params->{comment} : ''; $bug->add_comment($comment, { isprivate => $attachment->isprivate, @@ -1240,13 +1240,14 @@ sub add_attachment $dbh->bz_commit_transaction; # Operation result to save into session (CustIS Bug 64562) - push @{$send_attrs->{added_attachments}}, { + Bugzilla->add_result_message({ + message => 'added_attachment', id => $attachment->id, bug_id => $attachment->bug_id, description => $attachment->description, contenttype => $attachment->contenttype, ctype_auto => $ctype_auto, - }; + }); } 1; diff --git a/Bugzilla/Bug.pm b/Bugzilla/Bug.pm index aa90f05a3..ededaf7dd 100644 --- a/Bugzilla/Bug.pm +++ b/Bugzilla/Bug.pm @@ -60,7 +60,7 @@ use POSIX qw(floor); use Scalar::Util qw(blessed); use base qw(Bugzilla::Object Exporter); -@Bugzilla::Bug::EXPORT = qw(RemoveVotes CheckIfVotedConfirmed LogActivityEntry); +@Bugzilla::Bug::EXPORT = qw(RemoveVotes LogActivityEntry); @Bugzilla::Bug::EXPORT_OK = @Bugzilla::Bug::EXPORT; ##################################################################### @@ -481,6 +481,7 @@ sub update # First check dependent field values $self->check_dependent_fields; $self->check_strict_isolation; + $self->check_votes; my $dbh = Bugzilla->dbh; my $user = Bugzilla->user; @@ -605,6 +606,9 @@ sub update $self->_sync_fulltext($method eq 'create'); } + # Prepare email notifications. + $self->prepare_mail_results($changes); + # Remove obsolete internal variables. delete $self->{_old_self}; delete $self->{added_comments}; @@ -617,6 +621,106 @@ sub update return $changes; } +sub prepare_mail_results +{ + my $self = shift; + my ($changes) = @_; + + my %notify_deps; + if ($self->{_old_self} && $self->bug_status != $self->{_old_self}->bug_status) + { + my $old_status = $self->{_old_self}->bug_status_obj; + my $new_status = $self->bug_status_obj; + + # If this bug has changed from opened to closed or vice-versa, + # then all of the bugs we block need to be notified. + if ($old_status->is_open != $new_status->is_open) + { + $notify_deps{$_} = 1 foreach @{$self->blocked}; + } + + # We may have zeroed the remaining time, if we moved into a closed + # status, so we should inform the user about that. + if (!$new_status->is_open && $changes->{remaining_time} && + !$changes->{remaining_time}->[1] && + Bugzilla->user->is_timetracker) + { + Bugzilla->add_result_message({ message => 'remaining_time_zeroed' }); + } + } + + # To get a list of all changed dependencies, convert the "changes" arrays + # into a long string, then collapse that string into unique numbers in + # a hash. + my $all_changed_deps = join(', ', @{ $changes->{dependson} || [] }); + $all_changed_deps = join(', ', @{ $changes->{blocked} || [] }, $all_changed_deps); + my %changed_deps = map { $_ => 1 } split(', ', $all_changed_deps); + # When clearing one field (say, blocks) and filling in the other + # (say, dependson), an empty string can get into the hash and cause + # an error later. + delete $changed_deps{''}; + + my $old_qa = $changes->{qa_contact} ? $changes->{qa_contact}->[0] : ''; + my $old_own = $changes->{assigned_to} ? $changes->{assigned_to}->[0] : ''; + my $old_cc = $changes->{cc} ? $changes->{cc}->[0] : ''; + + # Let the user know the bug was changed and who did and didn't + # receive email about the change. + my $type = 'bug'; + if (!$self->{_old_self}) + { + $type = 'created'; + } + elsif ($self->{added_comments} && grep { $_->{type} == CMT_POPULAR_VOTES } @{$self->{added_comments}}) + { + $type = 'votes'; + } + else + { + $type = 'bug'; + } + Bugzilla->add_result_message({ + message => 'bugmail', + type => $type, + bug_id => $self->id, + mailrecipients => { + cc => [ split /[\s,]+/, $old_cc ], + owner => $old_own, + qacontact => $old_qa, + changer => Bugzilla->user->login, + }, + }); + + # If the bug was marked as a duplicate, we need to notify users on the + # other bug of any changes to that bug. + my $new_dup_id = $changes->{dup_id} ? $changes->{dup_id}->[1] : undef; + if ($new_dup_id) + { + # Let the user know a duplication notation was added to the original bug. + Bugzilla->add_result_message({ + message => 'bugmail', + mailrecipients => { changer => Bugzilla->user->login }, + bug_id => $new_dup_id, + type => 'dupe', + }); + } + + my %all_dep_changes = (%notify_deps, %changed_deps); + foreach my $id (sort { $a <=> $b } (keys %all_dep_changes)) + { + # Let the user (if he is able to see the bug) know we checked to + # see if we should email notice of this change to users with a + # relationship to the dependent bug and who did and didn't + # receive email about it. + Bugzilla->add_result_message({ + message => 'bugmail', + type => 'dep', + mailrecipients => { changer => Bugzilla->user->login }, + bug_id => $id, + }); + } +} + # There is no guarantee that any setters were called after creating an # empty object, so we must make sure all fields have allowed values. sub check_default_values @@ -643,6 +747,21 @@ sub check_default_values } } # Add some default values manually + if (!$self->id && !exists $self->{groups_in}) + { + # Add default product groups + my @gids; + my $controls = $self->product_obj->group_controls; + foreach my $gid (keys %$controls) + { + if ($controls->{$gid}->{membercontrol} == CONTROLMAPDEFAULT && Bugzilla->user->in_group_id($gid) || + $controls->{$gid}->{othercontrol} == CONTROLMAPDEFAULT && !Bugzilla->user->in_group_id($gid)) + { + push @gids, $gid; + } + } + $self->{groups_in} = \@gids; + } $self->set('groups', [ map { $_->id } @{$self->groups_in} ]); $self->{cc} = $self->component_obj->initial_cc if !$self->{cc}; $self->{everconfirmed} ||= 0; @@ -653,6 +772,18 @@ sub check_default_values $self->{creation_ts} = $self->{delta_ts} if !defined $self->{creation_ts}; } +# Check vote count after product change +sub check_votes +{ + my $self = shift; + if ($self->id && $self->{_old_self}->product_id != $self->product_id) + { + my $votes = RemoveVotes($self->id, 0, 'votes_bug_moved'); + $self->{votes} = $votes if defined $votes; + $self->check_if_voted_confirmed(); + } +} + # FIXME cache it sub get_dependent_check_order { @@ -1096,7 +1227,18 @@ sub save_cc push @{$self->{restricted_cc}}, $_; } } - $self->{restricted_cc} = undef if !@{$self->{restricted_cc}}; + if (@{$self->{restricted_cc}}) + { + Bugzilla->add_result_message({ + message => 'cc_list_restricted', + restricted_cc => [ map { $_->login } @{ $self->{restricted_cc} } ], + cc_restrict_group => $self->product_obj->cc_group, + }); + } + else + { + $self->{restricted_cc} = undef; + } } my $removed_cc = [ grep { !$new_cc{$_} } keys %old_cc ]; @@ -1998,6 +2140,8 @@ sub _set_keywords { my ($self, $data) = @_; + $data = { 'keywords' => $data, 'descriptions' => {} } if !ref $data; + my $old = $self->keyword_objects; my $new = $old; @@ -3668,24 +3812,21 @@ sub RemoveVotes my $dbh = Bugzilla->dbh; my $rows = $dbh->selectall_arrayref( - "SELECT profiles.login_name, profiles.userid, votes.vote_count," . + "SELECT profiles.userid, votes.vote_count," . " products.votesperuser, products.maxvotesperbug FROM profiles" . " LEFT JOIN votes ON profiles.userid = votes.who" . " LEFT JOIN bugs ON votes.bug_id = bugs.bug_id" . " LEFT JOIN products ON products.id = bugs.product_id" . " WHERE votes.bug_id = ?" . - ($who ? " AND votes.who = $who" : "") + ($who ? " AND votes.who = ?" : ""), undef, $id, ($who ? $who : ()) ); - # @messages stores all emails which have to be sent, if any. - # This array is passed to the caller which will send these emails itself. - my @messages = (); - if (@$rows) { + my $mails = []; foreach my $ref (@$rows) { - my ($name, $userid, $oldvotes, $votesperuser, $maxvotesperbug) = (@$ref); + my ($userid, $oldvotes, $votesperuser, $maxvotesperbug) = (@$ref); $maxvotesperbug = min($votesperuser, $maxvotesperbug); @@ -3721,41 +3862,37 @@ sub RemoveVotes # Now lets send the e-mail to alert the user to the fact that their votes have # been reduced or removed. - my $vars = { - to => $name . Bugzilla->params->{emailsuffix}, - bugid => $id, + push @$mails, { + userid => $userid, reason => $reason, votesremoved => $removedvotes, votesold => $oldvotes, votesnew => $newvotes, }; - - my $voter = new Bugzilla::User($userid); - my $template = Bugzilla->template_inner($voter->settings->{lang}->{value}); - - my $msg; - $template->process("email/votes-removed.txt.tmpl", $vars, \$msg); - push @messages, $msg; } - Bugzilla->template_inner(''); + if (@$mails) + { + Bugzilla->add_result_message({ + message => 'votes-removed', + bug_id => $id, + notify_data => $mails, + }); + } my $votes = $dbh->selectrow_array( "SELECT SUM(vote_count) FROM votes WHERE bug_id = ?", undef, $id ) || 0; $dbh->do("UPDATE bugs SET votes = ? WHERE bug_id = ?", undef, $votes, $id); + return $votes; } - - # Now return the array containing emails to be sent. - return @messages; + return undef; } # If a user votes for a bug, or the number of votes required to # confirm a bug has been reduced, check if the bug is now confirmed. -sub CheckIfVotedConfirmed +sub check_if_voted_confirmed { - my $id = shift; - my $bug = new Bugzilla::Bug($id); - + my $bug = shift; my $ret = 0; if (!$bug->everconfirmed && $bug->product_obj->votes_to_confirm && $bug->votes >= $bug->product_obj->votes_to_confirm) @@ -3782,6 +3919,7 @@ sub CheckIfVotedConfirmed $bug->{bug_status} = $new_status; $bug->{everconfirmed} = 1; delete $bug->{status}; # Contains the status object. + $ret = 1; } else { @@ -3789,9 +3927,6 @@ sub CheckIfVotedConfirmed # Do not call $bug->set(), for the same reason as above. $bug->{everconfirmed} = 1; } - $bug->update(); - - $ret = 1; } return $ret; } @@ -3993,6 +4128,39 @@ sub check_can_change_field return 0; } +# +# Procedural helper, used in importxls.cgi and email_in.pl +# + +# Create or update a bug +sub create_or_update +{ + my ($fields_in) = @_; + my $bug = $fields_in->{bug_id} && Bugzilla::Bug->new(delete $fields_in->{bug_id}) || Bugzilla::Bug->new; + # We still rely on product and component being set first + my @set_fields = ('product', 'component', grep { $_ ne 'product' && + $_ ne 'component' && $_ ne 'comment' && $_ ne 'work_time' } keys %$fields_in); + $bug->set($_ => $fields_in->{$_}) for @set_fields; + if (exists $fields_in->{comment}) + { + $bug->add_comment($fields_in->{comment}, { + work_time => $fields_in->{work_time}, + }); + delete $fields_in->{comment}; + delete $fields_in->{work_time}; + } + if (exists $fields_in->{blocked} || exists $fields_in->{dependson}) + { + $fields_in->{blocked} ||= join ',', @{ $bug->blocked }; + $fields_in->{dependson} ||= join ',', @{ $bug->dependson }; + $bug->set_dependencies({ dependson => $fields_in->{dependson}, blocked => $fields_in->{blocked} }); + delete $fields_in->{blocked}; + delete $fields_in->{dependson}; + } + $bug->update; + return $bug; +} + # # Field Validation # diff --git a/Bugzilla/BugMail.pm b/Bugzilla/BugMail.pm index 795f286e8..fcf228eb8 100644 --- a/Bugzilla/BugMail.pm +++ b/Bugzilla/BugMail.pm @@ -65,32 +65,36 @@ use constant REL_NAMES => { REL_GLOBAL_WATCHER, "GlobalWatcher" }; -use base qw(Exporter); -our @EXPORT = qw(send_results); - # Used to send email when an update is done. sub send_results { shift if $_[0] eq __PACKAGE__; my ($vars) = @_; - $vars->{commentsilent} = Bugzilla->cgi->param('commentsilent') ? 1 : 0; - if (Bugzilla->cgi->param('dontsendbugmail')) - { - return $vars; - } - if ($vars->{type} eq 'flag') + next if $vars->{message} eq 'bugmail' && $vars->{sent_bugmail}; + # FIXME check if commentsilent is working correctly + if ($vars->{message} eq 'flagmail') { + $vars->{message} = 'bugmail'; + $vars->{type} = 'flag'; $vars->{sent_bugmail} = SendFlag($vars->{notify_data}); $vars->{new_flag} = { name => $vars->{notify_data}->{flag} ? $vars->{notify_data}->{flag}->name : $vars->{notify_data}->{old_flag}->name, status => $vars->{notify_data}->{flag} ? $vars->{notify_data}->{flag}->status : 'X', }; - delete $vars->{notify_data}; # erase data, without - JSON encode error $vars->{commentsilent} = 0; # Custis Bug 132647 + delete $vars->{notify_data}; # erase data, don't store it in session } - else + elsif ($vars->{message} eq 'votes-removed') + { + $vars->{message} = 'bugmail'; + $vars->{sent_bugmail} = SendVotesRemoved($vars); + delete $vars->{notify_data}; # erase data, don't store it in session + } + elsif ($vars->{message} eq 'bugmail') { $vars->{sent_bugmail} = Send($vars->{bug_id}, $vars->{mailrecipients}, $vars->{commentsilent}); + # FIXME Don't take commentsilent from cgi here + $vars->{commentsilent} = Bugzilla->cgi->param('commentsilent') ? 1 : 0; } return $vars; } @@ -161,6 +165,26 @@ sub SendFlag return { sent => \@sent, excluded => \@excluded }; } +sub SendVotesRemoved +{ + my ($vars) = @_; + + my @to; + for (@{$vars->{notify_data}}) + { + $_->{bugid} = $vars->{bug_id}; + my $voter = new Bugzilla::User($_->{userid}); + my $template = Bugzilla->template_inner($voter->settings->{lang}->{value}); + my $msg; + $template->process("email/votes-removed.txt.tmpl", $_, \$msg); + MessageToMTA($msg); + push @to, $voter->login; + } + Bugzilla->template_inner(''); + + return { sent => \@to, excluded => [] }; +} + # This is a bit of a hack, basically keeping the old system() # cmd line interface. Should clean this up at some point. # diff --git a/Bugzilla/DB/Schema.pm b/Bugzilla/DB/Schema.pm index 1dc6a3704..d7f5509d9 100644 --- a/Bugzilla/DB/Schema.pm +++ b/Bugzilla/DB/Schema.pm @@ -214,13 +214,11 @@ use constant FIELD_TABLE_SCHEMA => { value => {TYPE => 'varchar(255)', NOTNULL => 1}, sortkey => {TYPE => 'INT2', NOTNULL => 1, DEFAULT => 0}, isactive => {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => 'TRUE'}, -# TODO parent_value_id => {TYPE => 'INT4', NOTNULL => 1, DEFAULT => 0}, ], # Note that bz_add_field_table should prepend the table name # to these index names. INDEXES => [ value_idx => {FIELDS => ['value'], TYPE => 'UNIQUE'}, -# TODO parent_value_idx => ['parent_value_id', 'sortkey'], sortkey_idx => ['sortkey', 'value'], ], }; diff --git a/Bugzilla/Flag.pm b/Bugzilla/Flag.pm index a1f37cd1d..db29a7e03 100644 --- a/Bugzilla/Flag.pm +++ b/Bugzilla/Flag.pm @@ -982,7 +982,7 @@ sub notify { return; } - # @TODO move "silent" indication out of cgi.commentsilent + # FIXME move "silent" indication out of cgi.commentsilent if (Bugzilla->cgi->param('commentsilent') && Bugzilla->user->settings->{silent_affects_flags}->{value} eq 'do_not_send') { @@ -1063,7 +1063,11 @@ sub notify { $recipients{$to}->settings->{lang}->{value} : $default_lang, }; } - Bugzilla->add_mail_result({ type => 'flag', bug_id => $bug->id, notify_data => $flagmail }); + Bugzilla->add_result_message({ + message => 'flagmail', + bug_id => $bug->id, + notify_data => $flagmail, + }); } # This is an internal function used by $bug->flag_types @@ -1138,7 +1142,7 @@ sub _flag_types { $flag->{allow_other} = 1; } $st = []; - # TODO remove hardcoded status list + # FIXME remove hardcoded status list push @$st, 'X' if $user->can_request_flag($type) || $flag->setter_id == $user->id; if ($type->is_active) { diff --git a/Bugzilla/Product.pm b/Bugzilla/Product.pm index d5f8d7bce..0c365e265 100644 --- a/Bugzilla/Product.pm +++ b/Bugzilla/Product.pm @@ -212,8 +212,7 @@ sub update ]; } - # We also have to fix votes. # FIXME WTF? - my @msgs; # Will store emails to send to voters. + # We also have to fix votes. if ($changes->{maxvotesperbug} || $changes->{votesperuser} || $changes->{votestoconfirm}) { # We cannot |use| these modules, due to dependency loops. @@ -233,11 +232,9 @@ sub update foreach my $vote (@$votes) { my ($who, $id) = (@$vote); - # If some votes are removed, RemoveVotes() returns a list - # of messages to send to voters. - push @msgs, Bugzilla::Bug::RemoveVotes($id, $who, 'votes_too_many_per_bug'); + Bugzilla::Bug::RemoveVotes($id, $who, 'votes_too_many_per_bug'); my $name = Bugzilla::User::user_id_to_login($who); - push @toomanyvotes_list, {id => $id, name => $name}; + push @toomanyvotes_list, { id => $id, name => $name }; } } $changes->{too_many_votes} = \@toomanyvotes_list; @@ -279,9 +276,7 @@ sub update ); foreach my $bug_id (@$bug_ids) { - # RemoveVotes() returns a list of messages to send - # in case some voters had too many votes. - push @msgs, Bugzilla::Bug::RemoveVotes($bug_id, $who, 'votes_too_many_per_user'); + Bugzilla::Bug::RemoveVotes($bug_id, $who, 'votes_too_many_per_user'); my $name = Bugzilla::User::user_id_to_login($who); push @toomanytotalvotes_list, {id => $bug_id, name => $name}; } @@ -299,8 +294,12 @@ sub update my @updated_bugs = (); foreach my $bug_id (@$bug_list) { - my $confirmed = Bugzilla::Bug::CheckIfVotedConfirmed($bug_id); - push (@updated_bugs, $bug_id) if $confirmed; + my $bug = Bugzilla::Bug->new($bug_id); + if ($bug->check_if_voted_confirmed) + { + $bug->update; + push @updated_bugs, $bug_id; + } } $changes->{confirmed_bugs} = \@updated_bugs; } @@ -444,21 +443,7 @@ sub update Bugzilla->user->clear_product_cache(); # Now that changes have been committed, we can send emails to voters. - foreach my $msg (@msgs) - { - MessageToMTA($msg); - } - - # And send out emails about changed bugs - require Bugzilla::BugMail; - foreach my $bug_id (@{ $changes->{confirmed_bugs} || [] }) - { - $changes->{confirmed_bugs_sent_bugmail}->{$bug_id} = Bugzilla::BugMail::send_results({ - mailrecipients => { changer => Bugzilla->user->login }, - bug_id => $bug_id, - type => "votes", - }); - } + Bugzilla->send_mail; Bugzilla->get_field(FIELD_NAME)->touch; diff --git a/Bugzilla/Search.pm b/Bugzilla/Search.pm index 2b674c4e8..633968281 100644 --- a/Bugzilla/Search.pm +++ b/Bugzilla/Search.pm @@ -2216,7 +2216,7 @@ sub _blocked_dependson } if (ref $self->{term}) { - # TODO move it to some function like combine_terms or so + # FIXME move it to some function like combine_terms or so $self->{term}->{table} = "(".$self->{term}->{table}. ($self->{term}->{neg} ? " LEFT" : " INNER"). " JOIN dependencies $t ON $self->{term}->{where})"; diff --git a/Bugzilla/Search/Saved.pm b/Bugzilla/Search/Saved.pm index 87bf02263..c1aab9ff8 100644 --- a/Bugzilla/Search/Saved.pm +++ b/Bugzilla/Search/Saved.pm @@ -83,7 +83,6 @@ sub new { detaint_natural($user_id) || ThrowCodeError('param_must_be_numeric', {function => $class . '::_init', param => 'user'}); - $name =~ s///; my @values = ($user_id, $name); $param = { condition => $condition, values => \@values }; } diff --git a/Bugzilla/Template.pm b/Bugzilla/Template.pm index dc19ae0ca..263d36a28 100644 --- a/Bugzilla/Template.pm +++ b/Bugzilla/Template.pm @@ -716,7 +716,7 @@ sub create { # "Dynamic" [% PROCESS ... %] # FYI "process" and "block_exists" are filters because only filters have access to context - process => [ sub { my ($context) = @_; return sub { $context->process(@_) } }, 1 ], + process => [ sub { my ($context, $vars) = @_; return sub { $context->process($_[0], $vars) } }, 1 ], # Check if a named block of the current template exists block_exists => [ sub { my ($context) = @_; return sub { diff --git a/Bugzilla/Util.pm b/Bugzilla/Util.pm index 9ca4c115a..99bce9a49 100644 --- a/Bugzilla/Util.pm +++ b/Bugzilla/Util.pm @@ -946,7 +946,7 @@ sub xml_dump_simple } elsif ($data =~ 'SCALAR') { - # TODO потенциально можно сохранять ссылки + # FIXME maybe save references? $r = xml_dump_simple($$data); } else diff --git a/attachment.cgi b/attachment.cgi index 1e794b0b8..9aadb1a35 100755 --- a/attachment.cgi +++ b/attachment.cgi @@ -582,11 +582,8 @@ sub insert } # Assign the bug to the user, if they are allowed to take it - my $owner = ''; if ($cgi->param('takebug')) { - # Make sure the person we are taking the bug from gets mail. - $owner = $bug->assigned_to->login; $bug->set('assigned_to', $user); } $bug->update($timestamp); @@ -607,30 +604,22 @@ sub insert $vars->{'header_done'} = 1; $vars->{'contenttypemethod'} = $cgi->param('contenttypemethod'); - Bugzilla->add_mail_result({ - mailrecipients => { 'changer' => $user->login, 'owner' => $owner }, - bug_id => $bugid, + Bugzilla->send_mail; + + Bugzilla->add_result_message({ + message => 'added_attachment', + id => $attachment->id, + bug_id => $attachment->bug_id, + description => $attachment->description, + contenttype => $attachment->contenttype, + ctype_auto => $vars->{contenttypemethod} eq 'autodetect', }); - send_results($_) for @{Bugzilla->get_mail_result}; + + Bugzilla::Hook::process('attachment_post_create_result', { vars => $vars }); # Save operation result into session and redirect (CustIS Bug 64562) - my $session_data = { - title => "Attachment ".$attachment->id." added to ".Bugzilla->messages->{terms}->{Bug}." ".$attachment->bug_id, - sent => Bugzilla->get_mail_result, - sent_attrs => { - added_attachments => [ { - id => $attachment->id, - bug_id => $attachment->bug_id, - description => $attachment->description, - contenttype => $attachment->contenttype, - ctype_auto => $vars->{contenttypemethod} eq 'autodetect', - } ], - }, - }; - - Bugzilla::Hook::process('attachment_post_create_result', { session_data => $session_data, vars => $vars }); - - Bugzilla->save_session_data($session_data); + my $title = "Attachment ".$attachment->id." added to ".Bugzilla->messages->{terms}->{Bug}." ".$attachment->bug_id; + Bugzilla->save_session_data({ title => $title }); print $cgi->redirect(-location => 'show_bug.cgi?id='.$attachment->bug_id); exit; } @@ -752,24 +741,17 @@ sub update { $vars->{'bugs'} = [$bug]; $vars->{'header_done'} = 1; - Bugzilla->add_mail_result({ - bug_id => $bug->id, - mailrecipients => { 'changer' => $user->login }, + Bugzilla->send_mail; + + Bugzilla->add_result_message({ + message => 'changed_attachment', + id => $attachment->id, + bug_id => $attachment->bug_id, + description => $attachment->description, }); - send_results($_) for @{Bugzilla->get_mail_result}; # Save operation result into session and redirect (CustIS Bug 64562) - Bugzilla->save_session_data({ - sent => Bugzilla->get_mail_result, - sent_attrs => { - changed_attachment => { - id => $attachment->id, - bug_id => $attachment->bug_id, - description => $attachment->description, - }, - }, - }); - + Bugzilla->save_session_data; print $cgi->redirect(-location => 'show_bug.cgi?id='.$attachment->bug_id); exit; } @@ -835,23 +817,16 @@ sub delete_attachment { $vars->{'bugs'} = [$bug]; $vars->{'header_done'} = 1; - Bugzilla->add_mail_result({ - bug_id => $bug->id, - mailrecipients => { 'changer' => $user->login }, - }); - send_results($_) for @{Bugzilla->get_mail_result}; + Bugzilla->send_mail; # Save operation result into session and redirect (CustIS Bug 64562) - Bugzilla->save_session_data({ - sent => Bugzilla->get_mail_result, - sent_attrs => { - changed_attachment => { - id => $attachment->id, - bug_id => $attachment->bug_id, - description => $attachment->description, - }, - }, + Bugzilla->add_result_message({ + message => 'changed_attachment', + id => $attachment->id, + bug_id => $attachment->bug_id, + description => $attachment->description, }); + Bugzilla->save_session_data; print $cgi->redirect(-location => 'show_bug.cgi?id='.$attachment->bug_id); exit; } diff --git a/editusers.cgi b/editusers.cgi index 512b33a4c..c858f74ff 100755 --- a/editusers.cgi +++ b/editusers.cgi @@ -654,13 +654,16 @@ if ($action eq 'search') { # Send mail about what we've done to bugs. # The deleted user is not notified of the changes. - foreach (keys(%updatedbugs)) { - # TODO save this into session and redirect - send_results({ + foreach (keys(%updatedbugs)) + { + # FIXME save this into session and redirect + Bugzilla->add_result_message({ + type => 'bugmail', bug_id => $_, mailrecipients => { 'changer' => $user->login }, }); } + Bugzilla->send_mail; ########################################################################### } elsif ($action eq 'activity') { diff --git a/email_in.pl b/email_in.pl index b4bfeb7f0..b0f69026a 100755 --- a/email_in.pl +++ b/email_in.pl @@ -201,55 +201,21 @@ sub post_bug { my ($fields) = @_; debug_print('Posting a new bug...'); - - my $user = Bugzilla->user; - - $fields->{cc} = delete $fields->{newcc} if $fields->{newcc}; - - # Restrict the bug to groups marked as Default. - # We let Bug->create throw an error if the product is - # not accessible, to throw the correct message. - $fields->{product} = '' if !defined $fields->{product}; - my $product = new Bugzilla::Product({ name => $fields->{product} }); - if ($product) - { - my @gids; - my $controls = $product->group_controls; - foreach my $gid (keys %$controls) - { - if ($controls->{$gid}->{membercontrol} == CONTROLMAPDEFAULT && $user->in_group_id($gid) || - $controls->{$gid}->{othercontrol} == CONTROLMAPDEFAULT && !$user->in_group_id($gid)) - { - push(@gids, $gid); - } - } - $fields->{groups} = \@gids; - } - - my ($retval, $non_conclusive_fields) = - Bugzilla::User::match_field({ - assigned_to => { type => 'single' }, - qa_contact => { type => 'single' }, - cc => { type => 'multi' } - }, $fields, MATCH_SKIP_CONFIRM); - - if ($retval != USER_MATCH_SUCCESS) - { - ThrowUserError('user_match_too_many', {fields => $non_conclusive_fields}); - } - - my $cgi = Bugzilla->cgi; - foreach my $field (keys %$fields) - { - $cgi->param(-name => $field, -value => $fields->{$field}); - } - $cgi->param('token', issue_session_token('createbug:')); - delete $cgi->{_VarHash}; - my $bug; - $Bugzilla::Error::IN_EVAL++; - my $vars = do 'post_bug.cgi'; - $Bugzilla::Error::IN_EVAL--; + eval + { + my ($retval, $non_conclusive_fields) = + Bugzilla::User::match_field({ + assigned_to => { type => 'single' }, + qa_contact => { type => 'single' }, + cc => { type => 'multi' } + }, $fields, MATCH_SKIP_CONFIRM); + if ($retval != USER_MATCH_SUCCESS) + { + ThrowUserError('user_match_too_many', { fields => $non_conclusive_fields }); + } + $bug = Bugzilla::Bug::create_or_update($fields); + }; if (my $err = $@) { my $format = "\n\nIncoming mail format for entering bugs:\n\n\@field = value\n\@field = value\n...\n\n\n"; @@ -263,7 +229,6 @@ sub post_bug } die $err; } - $bug = $vars->{bug}; if ($bug) { debug_print("Created bug " . $bug->id); @@ -272,68 +237,6 @@ sub post_bug return undef; } -sub process_bug -{ - my ($fields_in) = @_; - my %fields = %$fields_in; - - my $bug_id = $fields{bug_id}; - $fields{id} = $bug_id; - delete $fields{bug_id}; - - debug_print("Updating Bug $fields{id}..."); - - my $bug = Bugzilla::Bug->check($bug_id); - - if ($fields{bug_status}) - { - $fields{knob} = $fields{bug_status}; - } - # If no status is given, then we only want to change the resolution. - elsif ($fields{resolution}) - { - $fields{knob} = 'change_resolution'; - $fields{resolution_knob_change_resolution} = $fields{resolution}; - } - if ($fields{dup_id}) - { - $fields{knob} = 'duplicate'; - } - - # Move @cc to @newcc as @cc is used by process_bug.cgi to remove - # users from the CC list when @removecc is set. - $fields{newcc} = delete $fields{cc} if $fields{cc}; - - # Make it possible to remove CCs. - if ($fields{removecc}) - { - $fields{cc} = [split(',', $fields{removecc})]; - $fields{removecc} = 1; - } - - my $cgi = Bugzilla->cgi; - foreach my $field (keys %fields) - { - $cgi->param(-name => $field, -value => $fields{$field}); - } - $cgi->param('longdesclength', scalar @{ $bug->comments }); - $cgi->param('token', issue_hash_token([$bug->id, $bug->delta_ts])); - delete $cgi->{_VarHash}; - - $Bugzilla::Error::IN_EVAL++; - do 'process_bug.cgi'; - $Bugzilla::Error::IN_EVAL--; - debug_print($@) if $@; - debug_print("Bug processed."); - - my $added_comment; - if (trim($fields{comment})) - { - $added_comment = $bug->comments->[-1]; - } - return ($bug, $added_comment); -} - sub handle_attachments { my ($bug, $attachments, $comment) = @_; @@ -614,7 +517,9 @@ if ($mail_fields->{group_ids}) my ($bug, $comment); if ($mail_fields->{bug_id}) { - ($bug, $comment) = process_bug($mail_fields); + debug_print("Updating Bug $mail_fields->{bug_id}..."); + $bug = Bugzilla::Bug::create_or_update($mail_fields); + $comment = $bug->comments->[-1] if trim($mail_fields->{comment}); } else { @@ -623,14 +528,8 @@ else handle_attachments($bug, $attachments, $comment); -# This is here for post_bug and handle_attachments, so that when posting a bug -# with an attachment, any comment goes out as an attachment comment. -# -# Eventually this should be sending the mail for process_bug, too, but we have -# to wait for $bug->update() to be fully used in email_in.pl first. So -# currently, process_bug.cgi does the mail sending for bugs, and this does -# any mail sending for attachments after the first one. -Bugzilla::BugMail::Send($bug->id, { changer => Bugzilla->user->login }); +Bugzilla->send_mail; + debug_print("Sent bugmail"); __END__ diff --git a/enter_bug.cgi b/enter_bug.cgi index 9168a151f..2ee1eee79 100755 --- a/enter_bug.cgi +++ b/enter_bug.cgi @@ -331,9 +331,11 @@ if ($cloned_bug_id) my $removed = $product->restrict_cc(\@cc, 'login_name'); if ($removed && @$removed) { - $vars->{restricted_cc} = [ map { $_->login } @$removed ]; - $vars->{cc_restrict_group} = $product->cc_group; - $vars->{message} = 'cc_list_restricted'; + Bugzilla->add_result_message({ + message => 'cc_list_restricted', + cc_restrict_group => $product->cc_group, + restricted_cc => [ map { $_->login } @$removed ], + }); } } diff --git a/extensions/BmpConvert/lib/BmpConvert.pm b/extensions/BmpConvert/lib/BmpConvert.pm index 57d5c2c3e..b299f9308 100644 --- a/extensions/BmpConvert/lib/BmpConvert.pm +++ b/extensions/BmpConvert/lib/BmpConvert.pm @@ -52,7 +52,8 @@ sub attachment_post_create sub attachment_post_create_result { my ($args) = @_; - $args->{session_data}->{sent_attrs}->{convertedbmp} = $args->{vars}->{convertedbmp} = $args->{vars}->{attachment}->{convertedbmp}; + my $r = Bugzilla->result_messages; + $r->[$#$r]->{convertedbmp} = $args->{vars}->{convertedbmp} = $args->{vars}->{attachment}->{convertedbmp}; return 1; } diff --git a/extensions/custis/lib/Checkers.pm b/extensions/custis/lib/Checkers.pm index 2d1f10926..24e7f07d8 100644 --- a/extensions/custis/lib/Checkers.pm +++ b/extensions/custis/lib/Checkers.pm @@ -151,26 +151,18 @@ sub freeze_failed_checkers my $failedbugs = shift; $failedbugs && @$failedbugs || return undef; return [ - map { [ $_->bug_id, [ map { $_->id } @{$_->{failed_checkers}} ] ] } - grep { @{$_->{failed_checkers} || []} } @$failedbugs + map { { + bug_id => $_->bug_id, + failed_checkers => [ map { { + name => $_->name, + is_fatal => $_->is_fatal, + is_freeze => $_->is_freeze, + message => $_->message, + } } @{$_->{failed_checkers}} ] + } } grep { @{$_->{failed_checkers} || []} } @$failedbugs ]; } -sub unfreeze_failed_checkers -{ - my $freezed = shift; - $freezed && @$freezed || return undef; - my @r; - for (@$freezed) - { - my ($bug, $cl) = @$_; - $bug = Bugzilla::Bug->check($bug); - $bug->{failed_checkers} = Bugzilla::Checker->new_from_list($cl); - push @r, $bug; - } - return \@r; -} - sub filter_failed_checkers { my ($checkers, $changes, $bug) = @_; @@ -299,13 +291,25 @@ sub bug_end_of_update # ругаемся и откатываем изменения, если есть заваленные проверки if (@{$bug->{failed_checkers}}) { - if (!alert($bug)) + alert($bug); + # запоминаем сообщение о зафейленных проверках в result_messages + my $found; + for my $msg (@{ Bugzilla->result_messages }) { - %{ $args->{changes} } = (); - $bug->{added_comments} = undef; + if ($msg->{message} eq 'checkers_failed') + { + $found = 1; + push @{$msg->{failed_checkers}}, @{ freeze_failed_checkers([ $bug ]) }; + last; + } + } + if (!$found) + { + Bugzilla->add_result_message({ + message => 'checkers_failed', + failed_checkers => freeze_failed_checkers([ $bug ]), + }); } - # запоминаем объект бага с зафейленными проверками в request_cache - push @{Bugzilla->request_cache->{failed_checkers} ||= []}, $bug; } return 1; diff --git a/extensions/custis/template/en/default/edit-checkers.html.tmpl b/extensions/custis/template/en/default/edit-checkers.html.tmpl index b49f13378..2cda70fb2 100644 --- a/extensions/custis/template/en/default/edit-checkers.html.tmpl +++ b/extensions/custis/template/en/default/edit-checkers.html.tmpl @@ -84,7 +84,7 @@ [% END %] [% IF checker.query_id AND !found %] - + [% END %] diff --git a/extensions/custis/template/en/default/failed-checkers.html.tmpl b/extensions/custis/template/en/default/failed-checkers.html.tmpl index afaa21730..51aa0fff3 100644 --- a/extensions/custis/template/en/default/failed-checkers.html.tmpl +++ b/extensions/custis/template/en/default/failed-checkers.html.tmpl @@ -1,5 +1,4 @@ [%# Интерфейс: f = массив багов с заполненным полем failed_checkers = массиву Bugzilla::Checker %] -[% lastbug = "" %]

Внесённые [% IF f.size == 1 %] diff --git a/extensions/custis/template/en/default/hook/global/field-descs-end.none.tmpl b/extensions/custis/template/en/default/hook/global/field-descs-end.none.tmpl deleted file mode 100644 index 2808064d6..000000000 --- a/extensions/custis/template/en/default/hook/global/field-descs-end.none.tmpl +++ /dev/null @@ -1,6 +0,0 @@ -[% IF in_template_var %] - [% vars.field_descs.flags = "Flags" %] - [% a = "flagtypes.name" %] - [% vars.field_descs.$a = "Flag Types" %] - [% vars.field_descs.requests = "Requests" %] -[% END %] diff --git a/extensions/custis/template/en/default/hook/global/header-aftermessage.html.tmpl b/extensions/custis/template/en/default/hook/global/header-aftermessage.html.tmpl deleted file mode 100644 index 776c0ef0e..000000000 --- a/extensions/custis/template/en/default/hook/global/header-aftermessage.html.tmpl +++ /dev/null @@ -1,7 +0,0 @@ -[% IF failed_checkers AND failed_checkers.size %] -

-
- [% PROCESS "failed-checkers.html.tmpl" f = failed_checkers %] -
-
-[% END %] diff --git a/extensions/custis/template/en/default/hook/global/user-error-errors.html.tmpl b/extensions/custis/template/en/default/hook/global/user-error-errors.html.tmpl index cb3795ceb..2d4f246c9 100644 --- a/extensions/custis/template/en/default/hook/global/user-error-errors.html.tmpl +++ b/extensions/custis/template/en/default/hook/global/user-error-errors.html.tmpl @@ -1,22 +1,4 @@ -[% IF error == "cc_group_restriction" %] - [% title = "CC Group Restriction" %] - User [% user %] is restricted to watch this bug. -[% ELSIF error == "rms_fields_empty" %] - [% title = "Some required fields are empty" %] - [% FOR nok = not_ok_bugs %] - [% fs = [] %] - [% fs.push("Sprint") IF nok.s %] - [% fs.push("Status Whiteboard") IF nok.w %] - [% fs.push("Agreement") IF nok.a %] - [% terms.Bug %] [%+ nok.bug.id %] - [% nok.bug.short_desc | html %]: You must fill in [% fs.join(", ") %] attribute[% IF fs.size > 1 %]s[% END %] before [% IF nok.bug.bug_status == "ASSIGNED" %]taking[% ELSE %]closing[% END %] this bug!
- [% END %] -[% ELSIF error == "import_fields_mandatory" %] - The following missing fields: [% fields.join(", ") | html %] are required to enter new bugs. -[% ELSIF error == "invalid_field_value" %] - The value "[% value_obj.name | html %]" of field [% value_obj.field.description | html %] - is unavailable for the selected value "[% controller | html %]" of - the controlling field [% value_obj.field.value_field.description | html %]. -[% ELSIF error == "move_worktime_empty" %] +[% IF error == "move_worktime_empty" %] Вы пытаетесь перенести время или распределить его в пропорции, взятой из [% terms.Bug %] [% bug_id | html %], но в нём нет списанного diff --git a/importxls.cgi b/importxls.cgi index 38d30a85d..05035f93c 100755 --- a/importxls.cgi +++ b/importxls.cgi @@ -26,7 +26,6 @@ use IO::File; # Constants use constant BUG_DAYS => 92; use constant XLS_LISTNAME => ''; -use constant MANDATORY_FIELDS => qw(short_desc product component); my $user = Bugzilla->login(LOGIN_REQUIRED); my $cgi = Bugzilla->cgi; @@ -194,7 +193,8 @@ else if (/^b_(.*?)_(\d+)$/so) { # bug fields - $bugs->{$2}->{(exists $name_tr->{$1} ? $name_tr->{$1} : $1)} = $ARGS->{$_}; + my $k = (exists $name_tr->{$1} ? $name_tr->{$1} : $1); + $bugs->{$2}->{$k} = $ARGS->{$_} if $k; } } my $r = 0; @@ -212,17 +212,8 @@ else $bug->{$_} ||= $bug_tpl->{$_} for keys %$bug_tpl; if ($bug->{enabled}) { - my $id; - if ($bug->{bug_id} && Bugzilla::Bug->new($bug->{bug_id})) - { - # If bug with this same ID exists - update it - $id = process_bug($bug, $bugmail, $vars); - } - else - { - # Else post new bug - $id = post_bug($bug, $bugmail, $vars); - } + # If bug with this ID exists - update it, else - post new bug + my $id = Bugzilla::Bug::create_or_update($bug)->id; if ($id) { $r++; @@ -239,8 +230,7 @@ else unless ($f) { # Send bugmail only after successful completion - Bugzilla->cgi->delete('dontsendbugmail'); - send_results($_) for @$bugmail; + Bugzilla->send_mail; Bugzilla->dbh->bz_commit_transaction; print $cgi->redirect(-location => 'importxls.cgi?'.http_build_query({ result => $r, @@ -371,167 +361,5 @@ sub get_row } ($col_min .. $col_max) ]; } -# TODO remove duplicate post_bug and process_bug code from here, -# their .cgi and email_in.pl/importxml.pl versions, and move to Bugzilla::Bug - -# Add a bug -sub post_bug -{ - my ($fields_in, $bugmail, $vars) = @_; - my $cgi = Bugzilla->cgi; - # FIXME mandatory fields check should be moved somewhere - my @unexist; - for (MANDATORY_FIELDS) - { - if (!exists $fields_in->{$_}) - { - push @unexist, $vars->{import_field_descs}->{$_}; - } - } - if (@unexist) - { - ThrowUserError('import_fields_mandatory', { fields => \@unexist }); - } - - # Simulate email usage with browser error mode - my $um = Bugzilla->usage_mode; - Bugzilla->usage_mode(USAGE_MODE_EMAIL); - Bugzilla->error_mode(ERROR_MODE_WEBPAGE); - $Bugzilla::Error::IN_EVAL++; - my $product = eval { Bugzilla::Product->check({ name => $fields_in->{product} }) }; - if (!$product) - { - return undef; - } - # Add default product groups - my @gids; - my $controls = $product->group_controls; - foreach my $gid (keys %$controls) - { - if ($controls->{$gid}->{membercontrol} == CONTROLMAPDEFAULT && Bugzilla->user->in_group_id($gid) || - $controls->{$gid}->{othercontrol} == CONTROLMAPDEFAULT && !Bugzilla->user->in_group_id($gid)) - { - $fields_in->{"bit-$gid"} = 1; - } - } - unless ($fields_in->{version}) - { - # Guess version - my $component; - eval - { - $component = Bugzilla::Component->new({ - product => $product, - name => $fields_in->{component}, - }); - }; - # If there is no default version in the component: - if (!$component || !($fields_in->{version} = ($component->default_version && $component->default_version_obj->name))) - { - my $vers = [ map ($_->name, @{$product->versions}) ]; - my $v; - if (($v = $cgi->cookie("VERSION-" . $product->name)) && - grep { $_ eq $v } @$vers) - { - # get from cookie - $fields_in->{version} = $v; - } - else - { - # or just the last one, like in enter_bug.cgi - $fields_in->{version} = $vers->[$#$vers]; - } - } - } - # Push params to $cgi - foreach my $field (keys %$fields_in) - { - $cgi->param(-name => $field, -value => $fields_in->{$field}); - } - $cgi->param(dontsendbugmail => 1); - $cgi->param(token => issue_session_token('createbug:')); - delete $cgi->{_VarHash}; - # Call post_bug.cgi - my $vars_out = do 'post_bug.cgi'; - $Bugzilla::Error::IN_EVAL--; - Bugzilla->usage_mode($um); - if ($vars_out) - { - my $bug_id = $vars_out->{bug}->id; - push @$bugmail, @{$vars_out->{sentmail}}; - return $bug_id; - } - return undef; -} - -sub process_bug -{ - my ($fields_in, $bugmail, $vars) = @_; - - my $um = Bugzilla->usage_mode; - Bugzilla->usage_mode(USAGE_MODE_EMAIL); - Bugzilla->error_mode(ERROR_MODE_WEBPAGE); - Bugzilla->cgi->param(-name => 'dontsendbugmail', -value => 1); - - my %fields = %$fields_in; - - my $bug_id = delete $fields{'bug_id'}; - $fields{'id'} = $bug_id; - - my $bug = Bugzilla::Bug->check($bug_id); - - # process_bug.cgi always "tries to set" these fields - $fields{$_} ||= $bug->$_ for qw(product component target_milestone version); - - if (exists $fields{blocked} || exists $fields{dependson}) - { - $fields{blocked} ||= join ',', @{ $bug->blocked }; - $fields{dependson} ||= join ',', @{ $bug->dependson }; - } - - if ($fields{'bug_status'}) { - $fields{'knob'} = $fields{'bug_status'}; - } - # If no status is given, then we only want to change the resolution. - elsif ($fields{'resolution'}) { - $fields{'knob'} = 'change_resolution'; - $fields{'resolution_knob_change_resolution'} = $fields{'resolution'}; - } - if ($fields{'dup_id'}) { - $fields{'knob'} = 'duplicate'; - } - - # Move @cc to @newcc as @cc is used by process_bug.cgi to remove - # users from the CC list when @removecc is set. - $fields{newcc} = delete $fields{cc} if $fields{cc}; - - # Make it possible to remove CCs. - if ($fields{'removecc'}) { - $fields{'cc'} = [split(',', $fields{'removecc'})]; - $fields{'removecc'} = 1; - } - - my $cgi = Bugzilla->cgi; - foreach my $field (keys %fields) { - $cgi->param(-name => $field, -value => $fields{$field}); - } - $cgi->param('longdesclength', scalar @{ $bug->comments }); - $cgi->param('token', issue_hash_token([$bug->id, $bug->delta_ts])); - - delete $cgi->{_VarHash}; - # FIXME All this is an ugly hack. Bug::update() should call anything needed, not process_bug.cgi - $Bugzilla::Error::IN_EVAL++; - my $vars_out = do 'process_bug.cgi'; - $Bugzilla::Error::IN_EVAL--; - Bugzilla->usage_mode($um); - - if ($vars_out) - { - push @$bugmail, @{$vars_out->{sentmail}}; - return $bug_id; - } - return undef; -} - 1; __END__ diff --git a/js/bug-visibility.js b/js/bug-visibility.js index 4ecf31d49..bf2201881 100644 --- a/js/bug-visibility.js +++ b/js/bug-visibility.js @@ -44,13 +44,14 @@ function initControllerField(i) function getSelectedIds(sel) { + var opt = {}; var lm = sel.id.length+2; if (sel.type == 'hidden' && sel.name == 'product') { // product is a special case - it is preselected as hidden field on bug creation form - return { product_id: true }; + opt[product_id] = true; + return opt; } - var opt = {}; for (var i = 0; i < sel.options.length; i++) { if (sel.options[i].selected) @@ -158,10 +159,10 @@ function handleControllerField(e, controller) { bz_createOptionInSelect(controlled, '---', ''); } - for (var i in field_metadata[controlled.id]['legal']) + for (var i in field_metadata[controlled.id].legal) { - controlled_value = field_metadata[controlled.id]['legal'][i]; - vis = checkValueVisibility(opt, field_metadata[controller.id]['values'][controlled_id][controlled_value[0]]); + controlled_value = field_metadata[controlled.id].legal[i]; + vis = checkValueVisibility(opt, field_metadata[controller.id].values[controlled_id][controlled_value[0]]); if (vis) { item = bz_createOptionInSelect(controlled, controlled_value[1], controlled_value[1]); diff --git a/mod_perl.pl b/mod_perl.pl index f7e320d7c..9e8f215c2 100644 --- a/mod_perl.pl +++ b/mod_perl.pl @@ -183,9 +183,7 @@ sub unload eval { undef &$sub }; if ($@) { - # TODO не выгружать то, что не можем выгрузить, ибо - # иначе часть выгружается, а часть нет, и потом всё - # равно всё дохнет. + # FIXME do not unload that we can't unload, because it unloads partly anyway and Bugzilla crashes warn "Can't unload sub '$sub' in '$file': $@"; return undef; } diff --git a/post_bug.cgi b/post_bug.cgi index 2c2120bae..e839b9438 100755 --- a/post_bug.cgi +++ b/post_bug.cgi @@ -263,7 +263,7 @@ elsif (defined($cgi->upload('data')) || $ARGS->{attachurl} || } else { - $vars->{message} = 'attachment_creation_failed'; + Bugzilla->add_result_message({ message => 'attachment_creation_failed' }); } } @@ -280,55 +280,16 @@ if ($token) $dbh->do('UPDATE tokens SET eventdata = ? WHERE token = ?', undef, "createbug:$id", $token); } -my $bug_sent = { bug_id => $id, type => 'created', mailrecipients => { changer => $user->login } }; -send_results($bug_sent); -my @all_mail_results = ($bug_sent); - -# Add flag notify to send_result -my $notify = Bugzilla->get_mail_result(); -send_results($_) for @$notify; -push @all_mail_results, @$notify; - -foreach my $dep (@{$bug->dependson || []}, @{$bug->blocked || []}) -{ - my $dep_sent = { - type => 'dep', - bug_id => $dep, - recipients => $bug_sent->{recipients}, - }; - send_results($dep_sent); - push @all_mail_results, $dep_sent; -} -$vars->{sentmail} = \@all_mail_results; +Bugzilla->send_mail; if (Bugzilla->usage_mode != USAGE_MODE_EMAIL) { - my $title = Bugzilla->messages->{terms}->{Bug}.' '.$bug->id.' Submitted – '.$bug->short_desc; - my $header = Bugzilla->messages->{terms}->{Bug}.' '.$bug->id.' Submitted'; - my $ses = { - sent => \@all_mail_results, - title => $title, - header => $header, - message => $vars->{message}, - }; - # CustIS Bug 38616 - CC list restriction - if (!$ses->{message} && $bug->{restricted_cc}) - { - $ses->{message_vars} = { - restricted_cc => [ map { $_->login } @{ $bug->{restricted_cc} } ], - cc_restrict_group => $bug->product_obj->cc_group, - }; - $ses->{message} = 'cc_list_restricted'; - } - if (Bugzilla->save_session_data($ses)) - { - print $cgi->redirect(-location => 'show_bug.cgi?id='.$bug->id); - } - else - { - $template->process("bug/create/created.html.tmpl", $vars) - || ThrowTemplateError($template->error()); - } + # FIXME title/header hardcode + Bugzilla->save_session_data({ + title => Bugzilla->messages->{terms}->{Bug}.' '.$bug->id.' Submitted – '.$bug->short_desc, + header => Bugzilla->messages->{terms}->{Bug}.' '.$bug->id.' Submitted', + }); + print $cgi->redirect(-location => 'show_bug.cgi?id='.$bug->id); } $vars; diff --git a/process_bug.cgi b/process_bug.cgi index 3c8b4333a..1b956e2bc 100755 --- a/process_bug.cgi +++ b/process_bug.cgi @@ -235,6 +235,7 @@ else $vars->{title_tag} = "bug_processed"; $vars->{commentsilent} = $ARGS->{commentsilent}; +my $next_bug_id; my $action; if ($ARGS->{id}) { @@ -242,28 +243,21 @@ if ($ARGS->{id}) if ($action eq 'next_bug') { my @bug_list; - if ($cgi->cookie("BUGLIST")) # TODO + if ($cgi->cookie("BUGLIST")) # FIXME { @bug_list = split /:/, $cgi->cookie("BUGLIST"); } my $cur = lsearch(\@bug_list, $ARGS->{id}); if ($cur >= 0 && $cur < $#bug_list) { - my $next_bug_id = $bug_list[$cur + 1]; + $next_bug_id = $bug_list[$cur + 1]; detaint_natural($next_bug_id); - if ($next_bug_id && $user->can_see_bug($next_bug_id)) + if ($next_bug_id && !$user->can_see_bug($next_bug_id)) { - # We create an object here so that send_results can use it - # when displaying the header. - $vars->{bug} = new Bugzilla::Bug($next_bug_id); + $next_bug_id = undef; } } } - # Include both action = 'same_bug' and 'nothing'. - else - { - $vars->{bug} = $first_bug; - } } else { @@ -513,10 +507,6 @@ foreach my $b (@bug_objects) $b->add_cc($_) foreach @cc_add; } -# TODO move saved state into a global object -my $send_results = []; -my $send_attrs = {}; - my $move_action = $ARGS->{action} || ''; if ($move_action eq Bugzilla->params->{'move-button-text'}) { @@ -548,10 +538,11 @@ if ($move_action eq Bugzilla->params->{'move-button-text'}) # Now send emails. foreach my $bug (@bug_objects) { - push @$send_results, send_results({ - mailrecipients => { 'changer' => $user->login }, - bug_id => $bug->id, + Bugzilla->add_result_message({ + message => 'bugmail', type => 'move', + bug_id => $bug->id, + mailrecipients => { 'changer' => $user->login }, }); } # Prepare and send all data about these bugs to the new database @@ -579,19 +570,14 @@ if ($move_action eq Bugzilla->params->{'move-button-text'}) $msg .= "\n"; MessageToMTA($msg); - # End the response page. - unless (Bugzilla->usage_mode == USAGE_MODE_EMAIL) - { - foreach (@$send_results) - { - $template->process("bug/process/results.html.tmpl", { %$vars, %$_ }) - || ThrowTemplateError($template->error()); - } - $template->process("bug/navigate.html.tmpl", $vars) - || ThrowTemplateError($template->error()); - $template->process("global/footer.html.tmpl", $vars) - || ThrowTemplateError($template->error()); - } + Bugzilla->send_mail; + + $template->process("global/header.html.tmpl", $vars) + || ThrowTemplateError($template->error()); + $template->process("bug/navigate.html.tmpl", $vars) + || ThrowTemplateError($template->error()); + $template->process("global/footer.html.tmpl", $vars) + || ThrowTemplateError($template->error()); exit; } @@ -605,9 +591,7 @@ if (!$ARGS->{id} && $ARGS->{dup_id}) ThrowUserError('dupe_not_allowed'); } -# Set the status, resolution, and dupe_of (if needed). This has to be done -# down here, because the validity of status changes depends on other fields, -# such as Target Milestone. +# Set the status, resolution, and dupe_of (if needed). foreach my $b (@bug_objects) { if (defined $ARGS->{bug_status}) @@ -626,9 +610,6 @@ foreach my $b (@bug_objects) Bugzilla::Hook::process('process_bug-pre_update', { bugs => \@bug_objects }); -# @msgs will store emails which have to be sent to voters, if any. -my @msgs; - Bugzilla->request_cache->{checkers_hide_error} = 1 if @bug_objects > 1; ############################## @@ -638,123 +619,25 @@ foreach my $bug (@bug_objects) { $dbh->bz_start_transaction(); - my $mail_count = @{Bugzilla->get_mail_result()}; - my $timestamp = $dbh->selectrow_array(q{SELECT LOCALTIMESTAMP(0)}); - my $old_status = $bug->{_old_self}->bug_status_obj; - my $changes = $bug->update($timestamp); + my $msg_count = @{Bugzilla->result_messages}; + my $changes = $bug->update; if ($bug->{failed_checkers} && @{$bug->{failed_checkers}} && !$bug->{passed_checkers}) { - # This means update is blocked - # and rollback_to_savepoint is already done in Checkers.pm - # Roll back flag mail - splice @{Bugzilla->get_mail_result()}, $mail_count; + # Update is blocked and rollback_to_savepoint is already done in Checkers.pm. + # Rollback mail results and result messages. + splice @{Bugzilla->result_messages}, $msg_count; next; } - my %notify_deps; - if ($changes->{bug_status}) - { - my $new_status = $bug->bug_status_obj; - - # If this bug has changed from opened to closed or vice-versa, - # then all of the bugs we block need to be notified. - if ($old_status->is_open != $new_status->is_open) - { - $notify_deps{$_} = 1 foreach @{$bug->blocked}; - } - - # We may have zeroed the remaining time, if we moved into a closed - # status, so we should inform the user about that. - if (!$new_status->is_open && $changes->{remaining_time} && - !$changes->{remaining_time}->[1] && - Bugzilla->user->in_group(Bugzilla->params->{timetrackinggroup})) - { - $vars->{message} = "remaining_time_zeroed"; - } - } - - # CustIS Bug 38616 - CC list restriction - if ($bug->{restricted_cc}) - { - $vars->{restricted_cc} = [ map { $_->login } @{$bug->{restricted_cc}} ]; - $vars->{cc_restrict_group} = $bug->product_obj->cc_group; - $vars->{message} = 'cc_list_restricted'; - } - - # To get a list of all changed dependencies, convert the "changes" arrays - # into a long string, then collapse that string into unique numbers in - # a hash. - my $all_changed_deps = join(', ', @{ $changes->{dependson} || [] }); - $all_changed_deps = join(', ', @{ $changes->{blocked} || [] }, $all_changed_deps); - my %changed_deps = map { $_ => 1 } split(', ', $all_changed_deps); - # When clearning one field (say, blocks) and filling in the other - # (say, dependson), an empty string can get into the hash and cause - # an error later. - delete $changed_deps{''}; - - if ($changes->{product}) - { - # If some votes have been removed, RemoveVotes() returns - # a list of messages to send to voters. - # We delay the sending of these messages till changes are committed. - push @msgs, RemoveVotes($bug->id, 0, 'votes_bug_moved'); - CheckIfVotedConfirmed($bug->id); - } - $dbh->bz_commit_transaction(); - - my $old_qa = $changes->{qa_contact} ? $changes->{qa_contact}->[0] : ''; - my $old_own = $changes->{assigned_to} ? $changes->{assigned_to}->[0] : ''; - my $old_cc = $changes->{cc} ? $changes->{cc}->[0] : ''; - - # Let the user know the bug was changed and who did and didn't - # receive email about the change. - push @$send_results, { - mailrecipients => { - cc => [split(/[\s,]+/, $old_cc)], - owner => $old_own, - qacontact => $old_qa, - changer => Bugzilla->user->login, - }, - bug_id => $bug->id, - type => "bug", - }; - - # If the bug was marked as a duplicate, we need to notify users on the - # other bug of any changes to that bug. - my $new_dup_id = $changes->{dup_id} ? $changes->{dup_id}->[1] : undef; - if ($new_dup_id) - { - # Let the user know a duplication notation was added to the - # original bug. - push @$send_results, { - mailrecipients => { changer => Bugzilla->user->login }, - bug_id => $new_dup_id, - type => "dupe", - }; - } - - my %all_dep_changes = (%notify_deps, %changed_deps); - foreach my $id (sort { $a <=> $b } (keys %all_dep_changes)) - { - # Let the user (if he is able to see the bug) know we checked to - # see if we should email notice of this change to users with a - # relationship to the dependent bug and who did and didn't - # receive email about it. - push @$send_results, { - mailrecipients => { changer => Bugzilla->user->login }, - bug_id => $id, - type => "dep", - }; - } } # CustIS Bug 68919 - Create multiple attachments to bug if (@bug_objects == 1) { - Bugzilla::Attachment::add_multiple($first_bug, $cgi, $send_attrs); + Bugzilla::Attachment::add_multiple($first_bug, $cgi); } $dbh->bz_commit_transaction(); @@ -763,100 +646,47 @@ $dbh->bz_commit_transaction(); # Send Emails # ############### -# TODO move votes removed mail to BugMail -# Now is a good time to send email to voters. -foreach my $msg (@msgs) -{ - MessageToMTA($msg); -} - # Send bugmail +Bugzilla->send_mail; -# Add flag notifications to send_results -my $notify = Bugzilla->get_mail_result(); -push @$send_results, @$notify; - -send_results($_) for @$send_results; -$vars->{sentmail} = $send_results; -$vars->{failed_checkers} = Bugzilla->request_cache->{failed_checkers}; - -my $bug; -if (Bugzilla->usage_mode == USAGE_MODE_EMAIL) +if (scalar(@bug_objects) > 1) { - # Do nothing. + Bugzilla->session_data({ title => Bugzilla->messages->{terms}->{Bugs} . ' processed' }); } -elsif (($action eq 'next_bug' or $action eq 'same_bug') && ($bug = $vars->{bug}) && $user->can_see_bug($bug)) +elsif ($action eq 'next_bug') { - if ($action eq 'same_bug') + if ($next_bug_id) { - # $bug->update() does not update the internal structure of - # the bug sufficiently to display the bug with the new values. - # (That is, if we just passed in the old Bug object, we'd get - # a lot of old values displayed.) - $bug = new Bugzilla::Bug($bug->id); - $vars->{bug} = $bug; - } - # Do redirect and exit - my $title; - if (scalar(@bug_objects) == 1) - { - # FIXME hard-coded template title, also in bug/show-header.html.tmpl - $title = Bugzilla->messages->{terms}->{Bug} . ' ' . $bug_objects[0]->id . ' processed – ' . - $bug->short_desc . ' – ' . $bug->product . '/' . $bug->component . ' – ' . - $bug->bug_status_obj->name . ($bug->resolution ? ' ' . $bug->resolution_obj->name : ''); + # Do not override the title, but show a message + Bugzilla->add_result_message({ message => 'next_bug_shown', bug_id => $next_bug_id }); } else { - $title = Bugzilla->messages->{terms}->{Bugs} . ' processed'; - } - $send_attrs->{nextbug} = $action eq 'next_bug' ? 1 : 0; - my $ses = { - sent => $send_results, - title => $title, - sent_attrs => $send_attrs, - # CustIS Bug 68921 - Correctness checkers - failed_checkers => Checkers::freeze_failed_checkers(Bugzilla->request_cache->{failed_checkers}), - }; - # CustIS Bug 38616 - CC list restriction - if (scalar(@bug_objects) == 1 && $bug_objects[0]->{restricted_cc}) - { - $ses->{message_vars} = { - restricted_cc => [ map { $_->login } @{ $bug_objects[0]->{restricted_cc} } ], - cc_restrict_group => $bug_objects[0]->product_obj->cc_group, - }; - $ses->{message} = 'cc_list_restricted'; - } - if (Bugzilla->save_session_data($ses)) - { - print $cgi->redirect(-location => 'show_bug.cgi?id='.$bug->id); - exit; + $action = 'nothing'; } } - -if ($action ne 'nothing' && $action ne 'next_bug' && $action ne 'same_bug') +elsif ($action eq 'same_bug') { - ThrowCodeError("invalid_post_bug_submit_action"); + # FIXME hard-coded template title, also in bug/show-header.html.tmpl + Bugzilla->session_data({ title => Bugzilla->messages->{terms}->{Bug} . ' ' . $first_bug->id . ' processed – ' . + $first_bug->short_desc . ' – ' . $first_bug->product . '/' . $first_bug->component . ' – ' . + $first_bug->bug_status_obj->name . ($first_bug->resolution ? ' ' . $first_bug->resolution_obj->name : '') }); } -# End the response page. -unless (Bugzilla->usage_mode == USAGE_MODE_EMAIL) +if (scalar(@bug_objects) == 1 && $action ne 'nothing' && Bugzilla->save_session_data) { - foreach (@$send_results) - { - $template->process("bug/process/results.html.tmpl", { %$vars, %$_ }) - || ThrowTemplateError($template->error()); - $vars->{header_done} = 1; - } - if (!$vars->{header_done}) - { - $template->process("global/header.html.tmpl", $vars) - || ThrowTemplateError($template->error()); - } + # Do redirect and exit + print $cgi->redirect(-location => 'show_bug.cgi?id='.($next_bug_id || $first_bug->id)); +} +else +{ + # End the response page. + $template->process("global/header.html.tmpl", $vars) + || ThrowTemplateError($template->error()); $template->process("bug/navigate.html.tmpl", $vars) || ThrowTemplateError($template->error()); $template->process("global/footer.html.tmpl", $vars) || ThrowTemplateError($template->error()); } -$vars; -__END__ +exit; diff --git a/show_bug.cgi b/show_bug.cgi index a8fecb38b..2d35f2b00 100755 --- a/show_bug.cgi +++ b/show_bug.cgi @@ -118,7 +118,7 @@ $vars->{bugids} = join(', ', @bugids); # Work out which fields we are displaying (currently XML only) # If no explicit list is defined, we show all fields. We then exclude any -# on the exclusion list. This is so you can say e.g. "Everything except +# on the exclusion list. This is so you can say e.g. "Everything except # attachments" without listing almost all the fields. my @fieldlist = ( Bugzilla::Bug->fields, 'flag', 'group', 'long_desc', @@ -155,31 +155,6 @@ my @keyword_list_out = map { { name => $_->{name} } } @keyword_list; $vars->{keyword_list} = \@keyword_list_out; # END Custis Bug 66910 -# Show previous operation result from session -my $sd; -if (Bugzilla->session && ($sd = Bugzilla->session_data) && $sd->{sent}) -{ - Bugzilla->save_session_data({ - sent => undef, - title => undef, - header => undef, - sent_attrs => undef, - failed_checkers => undef, - message => undef, - message_vars => undef, - }); - $vars->{last_title} = $sd->{title}; - $vars->{last_header} = $sd->{header}; - $vars->{sentmail} = $sd->{sent}; - $vars->{failed_checkers} = Checkers::unfreeze_failed_checkers($sd->{failed_checkers}); - if ($sd->{message}) - { - $vars->{message} = $sd->{message}; - $vars->{$_} = $sd->{message_vars}->{$_} for keys %{$sd->{message_vars} || {}}; - } - $vars->{$_} = $sd->{sent_attrs}->{$_} for keys %{$sd->{sent_attrs} || {}}; -} - Bugzilla->cgi->send_header($format->{ctype}); $template->process($format->{template}, $vars) || ThrowTemplateError($template->error()); diff --git a/skins/standard/global.css b/skins/standard/global.css index 6c319a67d..e58f81ba1 100644 --- a/skins/standard/global.css +++ b/skins/standard/global.css @@ -549,7 +549,7 @@ filter:mask(); .buglist-navbar { float: left; margin: 4pt; font-size: 120%; padding: 2pt; } .user-error-div { margin: 20px; padding: 10px; font-size: 130%; font-family: sans-serif; border: 10px solid red; background: white; } -.user-error-div-first { font-size: 150%; background-color: #ffd0d0; padding: 10px; } +.user-error-div-first { background-color: #ffd0d0; padding: 10px; } .quicksearch { width: 300px; } diff --git a/template/en/default/admin/components/list.html.tmpl b/template/en/default/admin/components/list.html.tmpl index 060efd3a9..ee2963b9b 100644 --- a/template/en/default/admin/components/list.html.tmpl +++ b/template/en/default/admin/components/list.html.tmpl @@ -65,6 +65,7 @@ { name => "isactive", heading => "Active", + yesno_field => 1, }, ] %] diff --git a/template/en/default/admin/products/updated.html.tmpl b/template/en/default/admin/products/updated.html.tmpl index 5bb188fae..12eb79eda 100644 --- a/template/en/default/admin/products/updated.html.tmpl +++ b/template/en/default/admin/products/updated.html.tmpl @@ -185,12 +185,7 @@

Checking unconfirmed [% terms.bugs %] in this product for any which now have sufficient votes...
[% IF changes.confirmed_bugs.size %] - [% FOREACH id = changes.confirmed_bugs %] - [%# This is INCLUDED instead of PROCESSED to avoid variables getting - overwritten, which happens otherwise %] - [% FOR k = changes.confirmed_bugs_sent_bugmail.$id.keys; $k = changes.confirmed_bugs_sent_bugmail.$id.$k; END %] - [% INCLUDE bug/process/results.html.tmpl header_done = 1 %] - [% END %] + →[% changes.confirmed_bugs.size %] [% terms.bugs %] confirmed. [% ELSE %] →there were none. [% END %] diff --git a/template/en/default/admin/users/edit.html.tmpl b/template/en/default/admin/users/edit.html.tmpl index 147510b05..d38bb3b21 100644 --- a/template/en/default/admin/users/edit.html.tmpl +++ b/template/en/default/admin/users/edit.html.tmpl @@ -15,8 +15,7 @@ [%# INTERFACE: # - # message: message tag specifying a global/messages.html.tmpl - # message + # message: message tag specifying a global/messages.html.tmpl message. # listselectionvalues: selection values to recreate the current user list. # editusers: is viewing user member of editusers? # otheruser: Bugzilla::User object of viewed user. diff --git a/template/en/default/attachment/created.html.tmpl b/template/en/default/attachment/created.html.tmpl deleted file mode 100644 index 35c8e403c..000000000 --- a/template/en/default/attachment/created.html.tmpl +++ /dev/null @@ -1,65 +0,0 @@ -[%# The contents of this file are subject to the Mozilla Public - # License Version 1.1 (the "License"); you may not use this file - # except in compliance with the License. You may obtain a copy of - # the License at http://www.mozilla.org/MPL/ - # - # Software distributed under the License is distributed on an "AS - # IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - # implied. See the License for the specific language governing - # rights and limitations under the License. - # - # The Original Code is the Bugzilla Bug Tracking System. - # - # The Initial Developer of the Original Code is Netscape Communications - # Corporation. Portions created by Netscape are - # Copyright (C) 1998 Netscape Communications Corporation. All - # Rights Reserved. - # - # Contributor(s): Myk Melez - #%] - -[%# INTERFACE: - # attachment: object of the attachment just created. - # contenttypemethod: string. How we got the content type of the attachment. - # Possible values: autodetect, list, manual. - #%] - -[% bug = bugs.0 %] -[% PROCESS "bug/show-header.html.tmpl" %] -[% PROCESS global/header.html.tmpl - title = "Attachment $attachment.id added to $terms.Bug $attachment.bug_id" -%] -

-
- Attachment #[% attachment.id %] - to [% "$terms.bug $attachment.bug_id" FILTER bug_link(attachment.bug_id) FILTER none %] created -
-
- [% PROCESS "bug/process/bugmail.html.tmpl" mailing_bugid = attachment.bug_id %] - [% IF convertedbmp %] -

- Note: [% terms.Bugzilla %] automatically converted your BMP image file to a - compressed PNG format. -

- [% END %] - [% IF contenttypemethod == 'autodetect' %] -

- Note: [% terms.Bugzilla %] automatically detected the content type - [% attachment.contenttype FILTER html %] for this attachment. If this is - incorrect, correct the value by editing the attachment's - details. -

- [% END %] - - [%# Links to more information about the changed bug. %] - [% Hook.process("links") %] -
-
- -

-Create - Another Attachment to [% terms.Bug %] [%+ attachment.bug_id %] -

- -[% PROCESS bug/show.html.tmpl %] diff --git a/template/en/default/attachment/updated.html.tmpl b/template/en/default/attachment/updated.html.tmpl deleted file mode 100644 index 7edde26fa..000000000 --- a/template/en/default/attachment/updated.html.tmpl +++ /dev/null @@ -1,44 +0,0 @@ -[%# The contents of this file are subject to the Mozilla Public - # License Version 1.1 (the "License"); you may not use this file - # except in compliance with the License. You may obtain a copy of - # the License at http://www.mozilla.org/MPL/ - # - # Software distributed under the License is distributed on an "AS - # IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - # implied. See the License for the specific language governing - # rights and limitations under the License. - # - # The Original Code is the Bugzilla Bug Tracking System. - # - # The Initial Developer of the Original Code is Netscape Communications - # Corporation. Portions created by Netscape are - # Copyright (C) 1998 Netscape Communications Corporation. All - # Rights Reserved. - # - # Contributor(s): Myk Melez - # Gervase Markham - #%] - -[%# INTERFACE: - # attachment: object of the attachment we just attached. - #%] - -[% bug = bugs.0 %] -[% PROCESS "bug/show-header.html.tmpl" %] -[% PROCESS global/header.html.tmpl - title = "Changes Submitted to Attachment $attachment.id of $terms.Bug $attachment.bug_id" -%] - -
-
Changes to - attachment [% attachment.id %] - of [% "$terms.bug $attachment.bug_id" FILTER bug_link(attachment.bug_id) FILTER none %] submitted -
-
- [% PROCESS "bug/process/bugmail.html.tmpl" mailing_bugid = attachment.bug_id %] - [%# Links to more information about the changed bug. %] - [% Hook.process("links") %] -
-
- -[% PROCESS bug/show.html.tmpl %] diff --git a/template/en/default/bug/checkaccess.html.tmpl b/template/en/default/bug/checkaccess.html.tmpl index b9a678cf4..e54929512 100644 --- a/template/en/default/bug/checkaccess.html.tmpl +++ b/template/en/default/bug/checkaccess.html.tmpl @@ -1,3 +1,7 @@ +[%# Listing of all users who have access to a bug + # License: Dual-license MPL 1.1+ or GPL 3.0+ + # Author(s): Vitaliy Filippov %] + [% INCLUDE global/header.html.tmpl title = "$terms.Bug $bug.id - Check access" %]

[% IF count_user_list > 0 %][% count_user_list %]Users[% ELSE %]Everyone[% END %] can see [% terms.Bug _ " " _ bug.id %]

diff --git a/template/en/default/bug/create/created.html.tmpl b/template/en/default/bug/create/created.html.tmpl deleted file mode 100644 index 4abc89051..000000000 --- a/template/en/default/bug/create/created.html.tmpl +++ /dev/null @@ -1,59 +0,0 @@ -[%# The contents of this file are subject to the Mozilla Public - # License Version 1.1 (the "License"); you may not use this file - # except in compliance with the License. You may obtain a copy of - # the License at http://www.mozilla.org/MPL/ - # - # Software distributed under the License is distributed on an "AS - # IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - # implied. See the License for the specific language governing - # rights and limitations under the License. - # - # The Original Code is the Bugzilla Bug Tracking System. - # - # The Initial Developer of the Original Code is Netscape Communications - # Corporation. Portions created by Netscape are - # Copyright (C) 1998 Netscape Communications Corporation. All - # Rights Reserved. - # - # Contributor(s): Gervase Markham - #%] - -[%# INTERFACE: - # id: number; the ID of the bug that was created. - # sentmail: array of hash; bugs for which BugMail should be sent, contains: - # type: string; type of change for this bug, either 'created' if this bug - # was created or 'dep' if it was added as a dependent/blocker - # bug_id: integer; the ID of the bug - # bug: object; Bugzilla::Bug object of the bug that was created (used in - # template bug/edit.html.tmpl - #%] - -[% PROCESS "bug/show-header.html.tmpl" %] -[% PROCESS global/header.html.tmpl - title = "$terms.Bug $id Submitted – $filtered_desc" - header = "$terms.Bug $id Submitted" -%] - -[% header_done = 1 %] - -[% FOREACH item = sentmail %] - [% PROCESS bug/process/results.html.tmpl - type = item.type - bug_id = item.bug_id - sent_bugmail = item.sent_bugmail - %] -[% END %] - -
- -
- -[% PROCESS bug/edit.html.tmpl %] - -
- -[% PROCESS bug/navigate.html.tmpl bottom_navigator => 1 %] - -
- -[% PROCESS global/footer.html.tmpl %] diff --git a/template/en/default/bug/field.html.tmpl b/template/en/default/bug/field.html.tmpl index ed0ce8066..08bab8853 100644 --- a/template/en/default/bug/field.html.tmpl +++ b/template/en/default/bug/field.html.tmpl @@ -175,10 +175,9 @@ [% END %] [% IF NOT value_found %] - [% IF value.defined %] + [% value = bug.get_object(field.name) %] + [% IF value %] [% FOR v = value %] - [%# FIXME use _obj accessor? %] - [% v = field.value_type.new(v) %] [% END %] [% END %] diff --git a/template/en/default/bug/navigate.html.tmpl b/template/en/default/bug/navigate.html.tmpl index 71e93c10e..b84a6f78c 100644 --- a/template/en/default/bug/navigate.html.tmpl +++ b/template/en/default/bug/navigate.html.tmpl @@ -29,7 +29,7 @@ [% terms.Bug %] [%# Links to more things users can do with this bug. %] [% Hook.process("links") %] -
  •  - Top of page
  • +
  •  - Top of page
  • [% END %] diff --git a/template/en/default/bug/process/bugmail.html.tmpl b/template/en/default/bug/process/bugmail.html.tmpl deleted file mode 100644 index 0b4785ab0..000000000 --- a/template/en/default/bug/process/bugmail.html.tmpl +++ /dev/null @@ -1,62 +0,0 @@ -[%# The contents of this file are subject to the Mozilla Public - # License Version 1.1 (the "License"); you may not use this file - # except in compliance with the License. You may obtain a copy of - # the License at http://www.mozilla.org/MPL/ - # - # Software distributed under the License is distributed on an "AS - # IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - # implied. See the License for the specific language governing - # rights and limitations under the License. - # - # The Original Code is the Bugzilla Bug Tracking System. - # - # The Initial Developer of the Original Code is Netscape Communications - # Corporation. Portions created by Netscape are - # Copyright (C) 1998 Netscape Communications Corporation. All - # Rights Reserved. - # - # Contributor(s): Bradley Baetz - # J. Paul Reed - #%] - -[%# INTERFACE: - # mailing_bugid: The bug ID that email is being sent for. - # sent_bugmail: The results of Bugzilla::BugMail::Send(). - #%] - -[% IF NOT commentsilent %] -
    -[% PROCESS emails - description = "Email sent to" - names = sent_bugmail.sent -%] - -[% PROCESS emails - description = "Excluding" - names = sent_bugmail.excluded -%] -
    -[% ELSE %] -Your changes marked as Silent. No mail is sent. -[% END %] - -[%############################################################################%] -[%# Block for a set of email addresses #%] -[%############################################################################%] - -[% BLOCK emails %] -
    [% description FILTER html %]:
    -
    - [% IF user.can_see_bug(mailing_bugid) %] - [% IF names.size > 0 %] - [%+ FOREACH name = names %] - [% name FILTER html %][% ", " UNLESS loop.last() %] - [% END %] - [% ELSE %] - no one - [% END %] - [% ELSE %] - (list of e-mails not available) - [% END %] -
    -[% END %] diff --git a/template/en/default/bug/process/header.html.tmpl b/template/en/default/bug/process/header.html.tmpl deleted file mode 100644 index 432312542..000000000 --- a/template/en/default/bug/process/header.html.tmpl +++ /dev/null @@ -1,44 +0,0 @@ -[%# The contents of this file are subject to the Mozilla Public - # License Version 1.1 (the "License"); you may not use this file - # except in compliance with the License. You may obtain a copy of - # the License at http://www.mozilla.org/MPL/ - # - # Software distributed under the License is distributed on an "AS - # IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - # implied. See the License for the specific language governing - # rights and limitations under the License. - # - # The Original Code is the Bugzilla Bug Tracking System. - # - # The Initial Developer of the Original Code is Netscape Communications - # Corporation. Portions created by Netscape are - # Copyright (C) 1998 Netscape Communications Corporation. All - # Rights Reserved. - # - # Contributor(s): Gervase Markham - #%] - -[%# INTERFACE: - # As global/header.html.tmpl. - #%] - -[% USE Bugzilla %] - -[% PROCESS "bug/show-header.html.tmpl" %] - -[% IF title_tag == "bug_processed" %] - [% title = BLOCK %] - [% IF Bugzilla.cgi.param('id') %] - [% terms.Bug %] [%+ id FILTER html %] - [% ELSE %] - [% terms.Bugs %] - [% END %] - processed - [% END %] -[% ELSIF title_tag == "mid_air" %] - [% title = "Mid-air collision!" %] -[% ELSIF title_tag == "change_votes" %] - [% title = "Change Votes" %] -[% END %] - -[% PROCESS global/header.html.tmpl %] diff --git a/template/en/default/bug/process/midair.html.tmpl b/template/en/default/bug/process/midair.html.tmpl index d1b0ae0e1..fc93eea01 100644 --- a/template/en/default/bug/process/midair.html.tmpl +++ b/template/en/default/bug/process/midair.html.tmpl @@ -27,9 +27,7 @@ # bug: Bugzilla::Bug; the bug being changed. #%] -[% UNLESS header_done %] - [% PROCESS bug/process/header.html.tmpl %] -[% END %] +[% PROCESS "bug/show-header.html.tmpl" title="Mid-air collision!" %]

    Mid-air collision detected!

    diff --git a/template/en/default/bug/process/results.html.tmpl b/template/en/default/bug/process/results.html.tmpl index bb31dd520..0a9ab2402 100644 --- a/template/en/default/bug/process/results.html.tmpl +++ b/template/en/default/bug/process/results.html.tmpl @@ -24,11 +24,13 @@ # type: string; the type of change/check that was made: "bug" when a bug # is changed, "dupe" when a duplication notation is added to a bug, # and "dep" when a bug is checked for changes to its dependencies. + # + # sent_bugmail: The results of Bugzilla::BugMail::Send(). + # + # commentsilent: boolean; whether sending of the e-mails was suppressed. #%] -[% UNLESS header_done %] - [% PROCESS bug/process/header.html.tmpl %] -[% END %] +[% USE Bugzilla %] [% DEFAULT type="bug" %] @@ -42,22 +44,57 @@ 'X' => "canceled" '?' => "requested" }; - title = { - 'bug' => "Changes submitted for $link" , - 'dupe' => "Duplicate notation added to $link" , - 'dep' => "Checking for dependency changes on $link" , - 'votes' => "$Link confirmed by number of votes" , - 'created' => "$Link has been added to the database" , - 'move' => "$Link has been moved to another database" , - 'flag' => "Flag $new_flag.name " _ statuses.${new_flag.status} , + titles = { + 'bug' => "Changes submitted for $link", + 'dupe' => "Duplicate notation added to $link", + 'dep' => "Checking for dependency changes on $link", + 'votes' => "$Link confirmed by number of votes", + 'created' => "$Link has been added to the database", + 'move' => "$Link has been moved to another database", + 'flag' => "Flag $new_flag.name " _ statuses.${new_flag.status}, + 'votes-removed' => "Votes removed from $Link in accordance with new product settings", } %]
    -
    [% title.$type %]
    +
    [% titles.$type %]
    - [% PROCESS "bug/process/bugmail.html.tmpl" mailing_bugid = bug_id %] + [% IF NOT commentsilent %] +
    + [% PROCESS emails + description = "Email sent to" + names = sent_bugmail.sent + %] + [% PROCESS emails + description = "Excluding" + names = sent_bugmail.excluded + %] +
    + [% ELSE %] + Your changes marked as Silent. No mail is sent. + [% END %] [%# Links to more information about the changed bug. %] [% Hook.process("links") %]
    + +[%############################################################################%] +[%# Block for a set of email addresses #%] +[%############################################################################%] + +[% BLOCK emails %] +
    [% description FILTER html %]:
    +
    + [% IF Bugzilla.user.can_see_bug(bug_id) %] + [% IF names.size > 0 %] + [%+ FOREACH name = names %] + [% name FILTER html %][% ", " UNLESS loop.last() %] + [% END %] + [% ELSE %] + no one + [% END %] + [% ELSE %] + (list of e-mails not available) + [% END %] +
    +[% END %] diff --git a/template/en/default/bug/process/unsubscribe.html.tmpl b/template/en/default/bug/process/unsubscribe.html.tmpl index d08ad0e7b..82032d66e 100644 --- a/template/en/default/bug/process/unsubscribe.html.tmpl +++ b/template/en/default/bug/process/unsubscribe.html.tmpl @@ -1,9 +1,9 @@ -[%# 1.0@bugzilla.org %] - -[% USE Bugzilla %] -[% cgi = Bugzilla.cgi %] +[%# Unsubsribe yourself from bug CC list with a single click + # License: Dual-license MPL 1.1+ or GPL 3.0+ + # Author(s): Vitaliy Filippov %] [% PROCESS global/header.html.tmpl %] +

    Removing you from CC list of bug #[% bug.id %]

    [% IF rm_cc_ok %] @@ -13,4 +13,3 @@ [% END %] [% PROCESS global/footer.html.tmpl %] - diff --git a/template/en/default/bug/process/verify-field-values.html.tmpl b/template/en/default/bug/process/verify-field-values.html.tmpl index a34680372..011fa2c35 100644 --- a/template/en/default/bug/process/verify-field-values.html.tmpl +++ b/template/en/default/bug/process/verify-field-values.html.tmpl @@ -1,9 +1,11 @@ -[% PROCESS global/header.html.tmpl - title = 'Verify Field Values' %] +[% USE Bugzilla %] +[% cgi = Bugzilla.cgi %] + +[% PROCESS global/header.html.tmpl title='Verify Field Values' %]
    -[% PROCESS "global/hidden-fields.html.tmpl" exclude = exclude_params_re %] +[% PROCESS "global/hidden-fields.html.tmpl" exclude=exclude_params_re %] [% IF incorrect_fields.size > 0 %]

    Verify [% incorrect_field_descs.join(', ') %]

    diff --git a/template/en/default/bug/process/verify-flags.html.tmpl b/template/en/default/bug/process/verify-flags.html.tmpl index 4b1c73578..0986dcf79 100644 --- a/template/en/default/bug/process/verify-flags.html.tmpl +++ b/template/en/default/bug/process/verify-flags.html.tmpl @@ -1,10 +1,12 @@ -[%# 1.0@bugzilla.org %] +[%# This page reminds the user of non-reset flag requests on each bug change. + # License: Dual-license MPL 1.1+ or GPL 3.0+ + # Author(s): Vitaliy Filippov, Stas Fomin %] [% USE Bugzilla %] [% cgi = Bugzilla.cgi %] -[% title = 'Verify flag requests' %] -[% PROCESS global/header.html.tmpl %] +[% PROCESS global/header.html.tmpl title='Verify flag requests' %] +

    Please, verify flags:

    diff --git a/template/en/default/bug/process/verify-worktime.html.tmpl b/template/en/default/bug/process/verify-worktime.html.tmpl index b076d8102..037806e46 100644 --- a/template/en/default/bug/process/verify-worktime.html.tmpl +++ b/template/en/default/bug/process/verify-worktime.html.tmpl @@ -1,22 +1,19 @@ -[%# 1.0@bugzilla.org %] +[%# This page reminds the user to add "Hours Worked" on each bug change. + # License: Dual-license MPL 1.1+ or GPL 3.0+ + # Author(s): Vitaliy Filippov, Stas Fomin %] -[% USE Bugzilla %] -[% cgi = Bugzilla.cgi %] -[% title = 'Verify working time' %] - -[% PROCESS global/header.html.tmpl %] +[% PROCESS global/header.html.tmpl title = 'Verify working time' %] [% PROCESS "global/hidden-fields.html.tmpl" exclude=("^work_time$") %] - +

    Please, verify working time:

    -

    Hours Worked:

    +

    Hours Worked:

    -

    +

    [% PROCESS global/footer.html.tmpl %] - diff --git a/template/en/default/bug/session_result.html.tmpl b/template/en/default/bug/session_result.html.tmpl deleted file mode 100644 index 908fec406..000000000 --- a/template/en/default/bug/session_result.html.tmpl +++ /dev/null @@ -1,63 +0,0 @@ -[%# This template shows result for previous operation loaded from session - # License: Dual-license MPL 1.1+ or GPL 3.0+ - # Author(s): Vitaliy Filippov %] - -[% IF added_attachments %] -[% FOR att = added_attachments %] -
    -
    - Attachment #[% att.id %] - to [% "$terms.bug $att.bug_id" FILTER bug_link(att.bug_id) FILTER none %] created -
    -
    - [% IF att.ctype_auto %] -

    - Note: [% terms.Bugzilla %] automatically detected the content type - [% att.contenttype | html %] for this attachment. If this is - incorrect, correct the value by editing the attachment's - details. -

    - [% END %] - [% Hook.process("added_attachment_links") %] -
    -
    -[% IF att.convertedbmp %] -

    - Note: [% terms.Bugzilla %] automatically converted your BMP image file to a - compressed PNG format. -

    -[% END %] -[% END %] -[% END %] - -[% IF changed_attachment %] -[% SET title = "Changes Submitted to Attachment $changed_attachment.id of $terms.Bug $changed_attachment.bug_id" %] -
    -
    Changes to - attachment [% changed_attachment.id %] - of [% "$terms.bug $changed_attachment.bug_id" FILTER bug_link(changed_attachment.bug_id) FILTER none %] submitted -
    -
    -[% END %] - -[% FOREACH item = sentmail %] - [% FOR k = item.keys; $k = item.$k; END %] - [% PROCESS bug/process/results.html.tmpl item %] - [% FOR k = item.keys; $k = ''; END %] -[% END %] - -[% IF added_attachments %] - - Create Another Attachment to [% terms.Bug %] [%+ added_attachments.0.bug_id %] -

    -[% END %] - -[% IF nextbug %] -
    -

    - The next [% terms.bug %] in your list is [% terms.bug %] - [% bug.bug_id %]: -

    -
    -[% END %] diff --git a/template/en/default/bug/show-header.html.tmpl b/template/en/default/bug/show-header.html.tmpl index c48427d9f..fb53ffe89 100644 --- a/template/en/default/bug/show-header.html.tmpl +++ b/template/en/default/bug/show-header.html.tmpl @@ -21,33 +21,23 @@ # Max Kanat-Alexander #%] -[%# This template should be called with PROCESS before processing - # "global/header.html.tmpl" in any template that is going to load the - # bug form. It expects only a "bug" object, and can even manage to get - # along without that. Some of these variables are just defaults that will - # be overridden by the calling templates. - #%] - [% USE Bugzilla %] -[% filtered_desc = bug.short_desc FILTER html %] -[% subheader = filtered_desc %] -[% filtered_timestamp = bug.delta_ts FILTER time %] -[% filtered_prodcomp = bug.product_obj.name _ '/' _ bug.component_obj.name | html %] -[% filtered_stat = bug.bug_status_obj.name _ ' ' _ bug.resolution_obj.name | html %] -[% title = "$terms.Bug $bug.bug_id – $filtered_desc – $filtered_prodcomp – $filtered_stat" %] -[% header = "$terms.Bug $bug.bug_id" %] -[% header_addl_info = "Last modified: $filtered_timestamp" %] -[% javascript_urls = [ "js/field.js", "js/calendar.js", "js/bug-visibility.js?rev=1397", "fieldvaluecontrol.cgi?user=${Bugzilla.user.id}" ] %] +[% subheader = bug.short_desc | html %] +[% DEFAULT title = "$terms.Bug $bug.bug_id – $bug.short_desc – " _ + "${bug.product_obj.name}/${bug.component_obj.name} – " _ + "${bug.bug_status_obj.name} _ ${bug.resolution_obj.name}" | html %] +[% DEFAULT header = "$terms.Bug $bug.bug_id" %] +[% header_addl_info = "Last modified: " _ bug.delta_ts | html %] +[% javascript_urls = [ "js/field.js", "js/calendar.js", "js/bug-visibility.js", "fieldvaluecontrol.cgi?user=${Bugzilla.user.id}" ] %] [% style_urls = [ "skins/standard/calendar.css", "skins/standard/show_bug.css", "skins/standard/comments.css" ] %] [% doc_section = "bug_page.html" %] - -[% bodyclasses = ['bz_bug', - "bz_status_${bug.bug_status_obj.name}", - "bz_product_${bug.product_obj.name}", - "bz_component_${bug.component_obj.name}", - "bz_bug_$bug.bug_id", - ] %] +[% bodyclasses = [ + 'bz_bug', "bz_status_${bug.bug_status_obj.name}", "bz_product_${bug.product_obj.name}", + "bz_component_${bug.component_obj.name}", "bz_bug_$bug.bug_id", +] %] [% FOREACH group = bug.groups_in %] [% bodyclasses.push("bz_group_$group.name") %] [% END %] + +[% PROCESS global/header.html.tmpl %] diff --git a/template/en/default/bug/show.html.tmpl b/template/en/default/bug/show.html.tmpl index cc2016d10..0403326ff 100644 --- a/template/en/default/bug/show.html.tmpl +++ b/template/en/default/bug/show.html.tmpl @@ -1,39 +1,10 @@ -[%# The contents of this file are subject to the Mozilla Public - # License Version 1.1 (the "License"); you may not use this file - # except in compliance with the License. You may obtain a copy of - # the License at http://www.mozilla.org/MPL/ - # - # Software distributed under the License is distributed on an "AS - # IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - # implied. See the License for the specific language governing - # rights and limitations under the License. - # - # The Original Code is the Bugzilla Bug Tracking System. - # - # The Initial Developer of the Original Code is Netscape Communications - # Corporation. Portions created by Netscape are - # Copyright (C) 1998 Netscape Communications Corporation. All - # Rights Reserved. - # - # Contributor(s): Gervase Markham - # Vaskin Kissoyan - # Bradley Baetz - # Max Kanat-Alexander - #%] +[%# Show a single bug + # License: Dual-license MPL 1.1+ or GPL 3.0+ + # Author(s): Vitaliy Filippov %] -[%# This script/template only handles one bug #%] [% bug = bugs.0 %] -[% IF !header_done %] - [% PROCESS "bug/show-header.html.tmpl" %] - [% IF last_title; SET title = last_title; END; - IF last_header; SET header = last_header; END; %] - [% PROCESS global/header.html.tmpl %] -[% END %] - -[% header_done = 1 %] - -[% PROCESS bug/session_result.html.tmpl %] +[% PROCESS "bug/show-header.html.tmpl" %] [% PROCESS bug/navigate.html.tmpl %] @@ -41,7 +12,7 @@
    -[% PROCESS bug/navigate.html.tmpl bottom_navigator => 1%] +[% PROCESS bug/navigate.html.tmpl bottom_navigator => 1 %]
    diff --git a/template/en/default/bug/votes/list-for-user.html.tmpl b/template/en/default/bug/votes/list-for-user.html.tmpl index f7e6037ba..cd5d7383e 100644 --- a/template/en/default/bug/votes/list-for-user.html.tmpl +++ b/template/en/default/bug/votes/list-for-user.html.tmpl @@ -38,26 +38,19 @@ # all_bug_ids: List of all bug ids the user has voted for, across all products #%] -[% IF !header_done %] - [% subheader = voting_user.login FILTER html %] - [% IF canedit %] - [% title = "Change Votes" %] - [% IF bug_id %] - [%# We .select and .focus the input so it works for textbox and - checkbox %] - [% onload = "document.forms['voting_form'].bug_" _ bug_id _ - ".select();document.forms['voting_form'].bug_" _ bug_id _ - ".focus()" %] - [% END %] - [% ELSE %] - [% title = "Show Votes" %] +[% subheader = voting_user.login FILTER html %] +[% IF canedit %] + [% title = "Change Votes" %] + [% IF bug_id %] + [%# We .select and .focus the input so it works for textbox and checkbox %] + [% onload = "document.forms['voting_form'].bug_" _ bug_id _ + ".select();document.forms['voting_form'].bug_" _ bug_id _ + ".focus()" %] [% END %] - [% PROCESS global/header.html.tmpl - style_urls = [ "skins/standard/voting.css" ] - %] [% ELSE %] -
    + [% title = "Show Votes" %] [% END %] +[% PROCESS global/header.html.tmpl style_urls = [ "skins/standard/voting.css" ] %] [% IF votes_recorded %]

    diff --git a/template/en/default/filterexceptions.pl b/template/en/default/filterexceptions.pl index 11d6d7940..0dc3bd2ea 100644 --- a/template/en/default/filterexceptions.pl +++ b/template/en/default/filterexceptions.pl @@ -349,11 +349,6 @@ 'attachment.id', ], -'attachment/created.html.tmpl' => [ - 'attachment.id', - 'attachment.bug_id', -], - 'attachment/edit.html.tmpl' => [ 'attachment.id', 'attachment.bug_id', @@ -377,10 +372,6 @@ 'flag.status' ], -'attachment/updated.html.tmpl' => [ - 'attachment.id', -], - 'attachment/diff-header.html.tmpl' => [ 'attachid', 'id', diff --git a/template/en/default/global/header.html.tmpl b/template/en/default/global/header.html.tmpl index 42cbf3e2a..821eb969c 100644 --- a/template/en/default/global/header.html.tmpl +++ b/template/en/default/global/header.html.tmpl @@ -37,8 +37,19 @@ # atomlink: Atom link URL, May contain HTML #%] +[% USE Bugzilla %] + [% IF message %] - [% PROCESS global/messages.html.tmpl %] + [% message = BLOCK %][% PROCESS global/messages.html.tmpl %][% END %] +[% END %] + +[% IF Bugzilla.session_data.title %] + [% title = Bugzilla.session_data.title %] + [% do_save_session = 1 %] +[% END %] +[% IF Bugzilla.session_data.header %] + [% header = Bugzilla.session_data.header %] + [% do_save_session = 1 %] [% END %] [% DEFAULT @@ -319,8 +330,8 @@ [% IF Param('new_functionality_msg') && Param('new_functionality_tsp') && user.read_new_functionality %]

    - -
    [% Param('new_functionality_msg') FILTER none %]
    + +
    [% Param('new_functionality_msg') FILTER none %]
    [% END %] @@ -329,3 +340,13 @@ [% END %] [% Hook.process('aftermessage') %] + +[%# Show result messages from the session and delete them %] +[% IF Bugzilla.result_messages.size %] + [% FOR m = Bugzilla.result_messages %] + [% "global/messages.html.tmpl" FILTER process(m) %] + [% END %] + [% do_save_session = 1 %] +[% END %] + +[% IF do_save_session; x = Bugzilla.delete_session_data('result_messages', 'title', 'header'); END %] diff --git a/template/en/default/global/message.txt.tmpl b/template/en/default/global/message.txt.tmpl index 318cec4f5..476fadeff 100644 --- a/template/en/default/global/message.txt.tmpl +++ b/template/en/default/global/message.txt.tmpl @@ -17,7 +17,6 @@ # Contributor(s): Max Kanat-Alexander #%] -[%# Yes, this may show some HTML. But it's the best we - # can do at the moment. %] -[% PROCESS global/messages.html.tmpl %] +[%# Yes, this may show some HTML. But it's the best we can do at the moment. %] +[% message = BLOCK %][% PROCESS global/messages.html.tmpl %][% END %] [% message FILTER txt %] diff --git a/template/en/default/global/messages.html.tmpl b/template/en/default/global/messages.html.tmpl index 14360c1e2..597955b9d 100644 --- a/template/en/default/global/messages.html.tmpl +++ b/template/en/default/global/messages.html.tmpl @@ -19,6 +19,88 @@ # Max Kanat-Alexander #%] +[%# Operation result messages - these are shown from the session + # and without automatic wrapping in
    %] + +[% BLOCK msg_bugmail %] + [% INCLUDE bug/process/results.html.tmpl %] +[% END %] + +[% BLOCK msg_added_attachment %] +
    +
    + Attachment #[% id %] + to [% "$terms.bug $bug_id" FILTER bug_link(bug_id) FILTER none %] created +
    +
    + [% IF ctype_auto %] +

    + Note: [% terms.Bugzilla %] automatically detected the content type + [% contenttype | html %] for this attachment. If this is + incorrect, correct the value by editing the attachment's + details. +

    + [% END %] +
    +
    + [% IF att.convertedbmp %] +

    + Note: [% terms.Bugzilla %] automatically converted your BMP image file to a + compressed PNG format. +

    + [% END %] +[% END %] + +[% BLOCK msg_changed_attachment %] + [% SET title = "Changes Submitted to Attachment $id of $terms.Bug $bug_id" %] +
    +
    Changes to attachment [% id %] + of [% "$terms.bug $bug_id" FILTER bug_link(bug_id) FILTER none %] submitted +
    +
    +[% END %] + +[% BLOCK msg_next_bug_shown %] +
    +

    + The next [% terms.bug %] in your list is [% terms.bug %] + [% bug_id %]: +

    +
    +[% END %] + +[% BLOCK msg_remaining_time_zeroed %] +

    + The [% field_descs.remaining_time | html %] field has been + set to zero automatically as part of closing this [% terms.bug %] + or moving it from one closed state to another. +

    +[% END %] + +[% BLOCK msg_cc_list_restricted %] +
    + CC list restricted to group [% cc_restrict_group | html %], + [% restricted_cc.join(', ') | html %] removed. +
    +[% END %] + +[% BLOCK msg_attachment_creation_failed %] +
    The [% terms.bug %] was created successfully, but attachment creation + failed. Please add your attachment by clicking the "Add an Attachment" link + below.
    +[% END %] + +[% BLOCK msg_checkers_failed %] + [% IF failed_checkers AND failed_checkers.size %] +
    +
    + [% INCLUDE "failed-checkers.html.tmpl" f = failed_checkers %] +
    +
    + [% END %] +[% END %] + [%# This is a list of all the possible messages. Please keep them in # alphabetical order by message tag, and leave a blank line between messages. #%] @@ -111,13 +193,6 @@ cannot change its password. [% END %] -[% BLOCK msg_attachment_creation_failed %] - The [% terms.bug %] was created successfully, but attachment creation - failed. - Please add your attachment by clicking the "Add an Attachment" link - below. -[% END %] - [% BLOCK msg_bug_group_description %] Access to [% terms.bugs %] in the [% product.name | html %] product [% END %] @@ -851,12 +926,6 @@ products you can choose from. [% END %] -[% BLOCK msg_remaining_time_zeroed %] - The [% field_descs.remaining_time | html %] field has been - set to zero automatically as part of closing this [% terms.bug %] - or moving it from one closed state to another. -[% END %] - [% BLOCK msg_report_created %] OK, you have a new saved report named [% reportname FILTER html %]. [% END %] @@ -981,28 +1050,15 @@ The workflow has been updated. [% END %] -[% BLOCK msg_cc_list_restricted %] - CC list restricted to group [% cc_restrict_group | html %], - [% restricted_cc.join(', ') | html %] removed. -[% END %] - [% IF message %] -[% message_tag = 'msg_' _ message %] -[% message = BLOCK %] - [% message_tag FILTER process %] -[% END %] - -[%# Give sensible error if error functions are used incorrectly. %] -[% IF !message %] - You are using [% terms.Bugzilla %]'s messaging functions incorrectly. You - passed in the string '[% message_tag %]'. The correct use is to pass - in a tag, and define that tag in the file messages.html.tmpl.
    -
    - If you are a [% terms.Bugzilla %] end-user seeing this message, please - save this page and send it to [% Param('maintainer') %]. -[% END %] - -[% IF !message %] - [% message = Hook.process('messages') %] -[% END %] + [% message_tag = message %] + [% message = BLOCK %][% 'msg_' _ message_tag FILTER process %][% END %] + [% IF !message %][% message = Hook.process('messages') %][% END %] + [% message %] + [%# Give sensible error if a message is unknown. %] + [% IF !message %] + Message '[% message_tag | html %]' is unknown.
    + If you are a [% terms.Bugzilla %] end-user seeing this message, please + save this page and send it to [% Param('maintainer') %]. + [% END %] [% END %] diff --git a/template/en/default/global/user-error.html.tmpl b/template/en/default/global/user-error.html.tmpl index 336c90a9b..2a79561ac 100644 --- a/template/en/default/global/user-error.html.tmpl +++ b/template/en/default/global/user-error.html.tmpl @@ -296,6 +296,11 @@ You may not search, or create saved searches, without any search terms. [% END %] +[% BLOCK error_cc_group_restriction %] + [% title = "CC Group Restriction" %] + User [% user %] is restricted to watch this bug. +[% END %] + [% BLOCK error_chart_too_large %] [% title = "Chart Too Large" %] Sorry, but 2000 x 2000 is the maximum size for a chart. @@ -514,6 +519,10 @@ (You specified '[% name FILTER html %]'.) [% END %] +[% BLOCK error_import_fields_mandatory %] + The following missing fields: [% fields.join(", ") | html %] are required to enter new bugs. +[% END %] + [% BLOCK error_invalid_field_name %] Can't use [% field FILTER html %] as a field name. [% END %] diff --git a/userprefs.cgi b/userprefs.cgi index 1d2690eab..115a82421 100755 --- a/userprefs.cgi +++ b/userprefs.cgi @@ -412,7 +412,7 @@ sub SaveSavedSearches my $sth_delete_ngm = $dbh->prepare('DELETE FROM namedquery_group_map WHERE namedquery_id = ?'); - # TODO batch update + # FIXME do batch updates # For user's own queries, update namedquery_group_map. my $group; diff --git a/votes.cgi b/votes.cgi index d70b214c5..861a7e388 100755 --- a/votes.cgi +++ b/votes.cgi @@ -332,39 +332,26 @@ sub record_votes { # Update the cached values in the bugs table my @updated_bugs = (); - my $sth_getVotes = $dbh->prepare("SELECT SUM(vote_count) FROM votes - WHERE bug_id = ?"); - - my $sth_updateVotes = $dbh->prepare("UPDATE bugs SET votes = ? - WHERE bug_id = ?"); - - foreach my $id (keys %affected) { + my $sth_getVotes = $dbh->prepare("SELECT SUM(vote_count) FROM votes WHERE bug_id = ?"); + my $sth_updateVotes = $dbh->prepare("UPDATE bugs SET votes = ? WHERE bug_id = ?"); + foreach my $id (keys %affected) + { $sth_getVotes->execute($id); my $v = $sth_getVotes->fetchrow_array || 0; $sth_updateVotes->execute($v, $id); - my $confirmed = Bugzilla::Bug::CheckIfVotedConfirmed($id); - push (@updated_bugs, $id) if $confirmed; + my $bug = Bugzilla::Bug->new($id); + if ($bug->check_if_voted_confirmed) + { + $bug->update; + push @updated_bugs, $id; + } } $dbh->bz_commit_transaction(); + Bugzilla->send_mail; - $vars->{'type'} = "votes"; - $vars->{'title_tag'} = 'change_votes'; - - foreach my $bug_id (@updated_bugs) - { - # TODO save this into session and redirect - my $sent = send_results({ - bug_id => $bug_id, - mailrecipients => { 'changer' => Bugzilla->user->login }, - type => "votes", - }); - $vars->{$_} = $sent->{$_} for keys %$sent; - - $template->process("bug/process/results.html.tmpl", $vars) - || ThrowTemplateError($template->error()); - # Set header_done to 1 only after the first bug. - $vars->{'header_done'} = 1; - } - $vars->{'votes_recorded'} = 1; + $vars->{title} = 'Change Votes'; + $vars->{votes_recorded} = 1; } + +exit;