diff options
Diffstat (limited to 'extensions/ShadowBugs/Extension.pm')
-rw-r--r-- | extensions/ShadowBugs/Extension.pm | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/extensions/ShadowBugs/Extension.pm b/extensions/ShadowBugs/Extension.pm new file mode 100644 index 000000000..a9a1e0861 --- /dev/null +++ b/extensions/ShadowBugs/Extension.pm @@ -0,0 +1,99 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This Source Code Form is "Incompatible With Secondary Licenses", as +# defined by the Mozilla Public License, v. 2.0. + +package Bugzilla::Extension::ShadowBugs; + +use strict; + +use base qw(Bugzilla::Extension); + +use Bugzilla::Bug; +use Bugzilla::Error; +use Bugzilla::Field; +use Bugzilla::User; + +our $VERSION = '1'; + +BEGIN { + *Bugzilla::is_cf_shadow_bug_hidden = \&_is_cf_shadow_bug_hidden; + *Bugzilla::Bug::cf_shadow_bug_obj = \&_cf_shadow_bug_obj; +} + +# Determine if the shadow-bug / shadowed-by fields are visibile on the +# specified bug. +sub _is_cf_shadow_bug_hidden { + my ($self, $bug) = @_; + + # completely hide unless you're a member of the right group + return 1 unless Bugzilla->user->in_group('can_shadow_bugs'); + + my $is_public = Bugzilla::User->new()->can_see_bug($bug->id); + if ($is_public) { + # hide on public bugs, unless it's shadowed + my $related = $bug->related_bugs(Bugzilla->process_cache->{shadow_bug_field}); + return 1 if !@$related; + } +} + +sub _cf_shadow_bug_obj { + my ($self) = @_; + return unless $self->cf_shadow_bug; + return $self->{cf_shadow_bug_obj} ||= Bugzilla::Bug->new($self->cf_shadow_bug); +} + +sub template_before_process { + my ($self, $args) = @_; + my $file = $args->{'file'}; + my $vars = $args->{'vars'}; + + Bugzilla->process_cache->{shadow_bug_field} ||= Bugzilla::Field->new({ name => 'cf_shadow_bug' }); + + return unless Bugzilla->user->in_group('can_shadow_bugs'); + return unless + $file eq 'bug/edit.html.tmpl' + || $file eq 'bug/show.html.tmpl' + || $file eq 'bug/show-header.html.tmpl'; + my $bug = exists $vars->{'bugs'} ? $vars->{'bugs'}[0] : $vars->{'bug'}; + return unless $bug && $bug->cf_shadow_bug; + $vars->{is_shadow_bug} = 1; + + if ($file eq 'bug/edit.html.tmpl') { + # load comments from other bug + $vars->{shadow_comments} = $bug->cf_shadow_bug_obj->comments; + } +} + +sub bug_end_of_update { + my ($self, $args) = @_; + + # don't allow shadowing non-public bugs + if (exists $args->{changes}->{cf_shadow_bug}) { + my ($old_id, $new_id) = @{ $args->{changes}->{cf_shadow_bug} }; + if ($new_id) { + if (!Bugzilla::User->new()->can_see_bug($new_id)) { + ThrowUserError('illegal_shadow_bug_public', { id => $new_id }); + } + } + } + + # if a shadow bug is made public, clear the shadow_bug field + if (exists $args->{changes}->{bug_group}) { + my $bug = $args->{bug}; + return unless my $shadow_id = $bug->cf_shadow_bug; + my $is_public = Bugzilla::User->new()->can_see_bug($bug->id); + if ($is_public) { + Bugzilla->dbh->do( + "UPDATE bugs SET cf_shadow_bug=NULL WHERE bug_id=?", + undef, $bug->id); + LogActivityEntry($bug->id, 'cf_shadow_bug', $shadow_id, '', + Bugzilla->user->id, $args->{timestamp}); + + } + } +} + +__PACKAGE__->NAME; |