summaryrefslogtreecommitdiffstats
path: root/extensions/InlineHistory/Extension.pm
diff options
context:
space:
mode:
Diffstat (limited to 'extensions/InlineHistory/Extension.pm')
-rw-r--r--extensions/InlineHistory/Extension.pm384
1 files changed, 194 insertions, 190 deletions
diff --git a/extensions/InlineHistory/Extension.pm b/extensions/InlineHistory/Extension.pm
index adbfa4c74..45f1120f8 100644
--- a/extensions/InlineHistory/Extension.pm
+++ b/extensions/InlineHistory/Extension.pm
@@ -24,223 +24,227 @@ our $VERSION = '1.5';
use constant MAXIMUM_ACTIVITY_COUNT => 500;
# don't show really long values
-use constant MAXIMUM_VALUE_LENGTH => 256;
+use constant MAXIMUM_VALUE_LENGTH => 256;
sub template_before_create {
- my ($self, $args) = @_;
- $args->{config}->{FILTERS}->{ih_short_value} = sub {
- my ($str) = @_;
- return length($str) <= MAXIMUM_VALUE_LENGTH
- ? $str
- : substr($str, 0, MAXIMUM_VALUE_LENGTH - 3) . '...';
- };
+ my ($self, $args) = @_;
+ $args->{config}->{FILTERS}->{ih_short_value} = sub {
+ my ($str) = @_;
+ return
+ length($str) <= MAXIMUM_VALUE_LENGTH
+ ? $str
+ : substr($str, 0, MAXIMUM_VALUE_LENGTH - 3) . '...';
+ };
}
sub template_before_process {
- my ($self, $args) = @_;
- my $file = $args->{'file'};
- my $vars = $args->{'vars'};
-
- return if $file ne 'bug/edit.html.tmpl';
-
- my $user = Bugzilla->user;
- my $dbh = Bugzilla->dbh;
- return unless $user->id && $user->settings->{'inline_history'}->{'value'} eq 'on';
-
- # note: bug/edit.html.tmpl doesn't support multiple bugs
- my $bug = exists $vars->{'bugs'} ? $vars->{'bugs'}[0] : $vars->{'bug'};
- my $bug_id = $bug->id;
-
- # build bug activity
- my ($activity) = $bug->can('get_activity')
- ? $bug->get_activity()
- : Bugzilla::Bug::GetBugActivity($bug_id);
- $activity = _add_duplicates($bug_id, $activity);
-
- if (scalar @$activity > MAXIMUM_ACTIVITY_COUNT) {
- $activity = [];
- $vars->{'ih_activity'} = 0;
- $vars->{'ih_activity_max'} = 1;
- return;
- }
-
- # allow other extensions to alter history
- Bugzilla::Hook::process('inline_history_activtiy', { activity => $activity });
-
- my %attachment_cache;
- foreach my $attachment (@{$bug->attachments}) {
- $attachment_cache{$attachment->id} = $attachment;
- }
-
- # build a list of bugs we need to check visibility of, so we can check with a single query
- my %visible_bug_ids;
-
- # augment and tweak
- foreach my $operation (@$activity) {
- # make operation.who an object
- $operation->{who} =
- Bugzilla::User->new({ name => $operation->{who}, cache => 1 });
-
- for (my $i = 0; $i < scalar(@{$operation->{changes}}); $i++) {
- my $change = $operation->{changes}->[$i];
-
- # make an attachment object
- if ($change->{attachid}) {
- $change->{attach} = $attachment_cache{$change->{attachid}};
- }
-
- # empty resolutions are displayed as --- by default
- # make it explicit here to enable correct display of the change
- if ($change->{fieldname} eq 'resolution') {
- $change->{removed} = '---' if $change->{removed} eq '';
- $change->{added} = '---' if $change->{added} eq '';
- }
-
- # make boolean fields true/false instead of 1/0
- my ($table, $field) = ('bugs', $change->{fieldname});
- if ($field =~ /^([^\.]+)\.(.+)$/) {
- ($table, $field) = ($1, $2);
- }
- my $column = $dbh->bz_column_info($table, $field);
- if ($column && $column->{TYPE} eq 'BOOLEAN') {
- $change->{removed} = '';
- $change->{added} = $change->{added} ? 'true' : 'false';
- }
-
- my $field_obj;
- if ($change->{fieldname} =~ /^cf_/) {
- $field_obj = Bugzilla::Field->new({ name => $change->{fieldname}, cache => 1 });
- $change->{fieldtype} = $field_obj->type;
- }
-
- # identify buglist changes
- if ($change->{fieldname} eq 'blocked' ||
- $change->{fieldname} eq 'dependson' ||
- $change->{fieldname} eq 'dupe' ||
- ($field_obj && $field_obj->type == FIELD_TYPE_BUG_ID)
- ) {
- $change->{buglist} = 1;
- foreach my $what (qw(removed added)) {
- my @buglist = split(/[\s,]+/, $change->{$what});
- foreach my $id (@buglist) {
- if ($id && $id =~ /^\d+$/) {
- $visible_bug_ids{$id} = 1;
- }
- }
- }
- }
-
- # split see-also
- if ($change->{fieldname} eq 'see_also') {
- my $url_base = Bugzilla->localconfig->{urlbase};
- foreach my $f (qw( added removed )) {
- my @values;
- foreach my $value (split(/, /, $change->{$f})) {
- my ($bug_id) = substr($value, 0, length($url_base)) eq $url_base
- ? $value =~ /id=(\d+)$/
- : undef;
- push @values, {
- url => $value,
- bug_id => $bug_id,
- };
- }
- $change->{$f} = \@values;
- }
+ my ($self, $args) = @_;
+ my $file = $args->{'file'};
+ my $vars = $args->{'vars'};
+
+ return if $file ne 'bug/edit.html.tmpl';
+
+ my $user = Bugzilla->user;
+ my $dbh = Bugzilla->dbh;
+ return
+ unless $user->id && $user->settings->{'inline_history'}->{'value'} eq 'on';
+
+ # note: bug/edit.html.tmpl doesn't support multiple bugs
+ my $bug = exists $vars->{'bugs'} ? $vars->{'bugs'}[0] : $vars->{'bug'};
+ my $bug_id = $bug->id;
+
+ # build bug activity
+ my ($activity)
+ = $bug->can('get_activity')
+ ? $bug->get_activity()
+ : Bugzilla::Bug::GetBugActivity($bug_id);
+ $activity = _add_duplicates($bug_id, $activity);
+
+ if (scalar @$activity > MAXIMUM_ACTIVITY_COUNT) {
+ $activity = [];
+ $vars->{'ih_activity'} = 0;
+ $vars->{'ih_activity_max'} = 1;
+ return;
+ }
+
+ # allow other extensions to alter history
+ Bugzilla::Hook::process('inline_history_activtiy', {activity => $activity});
+
+ my %attachment_cache;
+ foreach my $attachment (@{$bug->attachments}) {
+ $attachment_cache{$attachment->id} = $attachment;
+ }
+
+# build a list of bugs we need to check visibility of, so we can check with a single query
+ my %visible_bug_ids;
+
+ # augment and tweak
+ foreach my $operation (@$activity) {
+
+ # make operation.who an object
+ $operation->{who}
+ = Bugzilla::User->new({name => $operation->{who}, cache => 1});
+
+ for (my $i = 0; $i < scalar(@{$operation->{changes}}); $i++) {
+ my $change = $operation->{changes}->[$i];
+
+ # make an attachment object
+ if ($change->{attachid}) {
+ $change->{attach} = $attachment_cache{$change->{attachid}};
+ }
+
+ # empty resolutions are displayed as --- by default
+ # make it explicit here to enable correct display of the change
+ if ($change->{fieldname} eq 'resolution') {
+ $change->{removed} = '---' if $change->{removed} eq '';
+ $change->{added} = '---' if $change->{added} eq '';
+ }
+
+ # make boolean fields true/false instead of 1/0
+ my ($table, $field) = ('bugs', $change->{fieldname});
+ if ($field =~ /^([^\.]+)\.(.+)$/) {
+ ($table, $field) = ($1, $2);
+ }
+ my $column = $dbh->bz_column_info($table, $field);
+ if ($column && $column->{TYPE} eq 'BOOLEAN') {
+ $change->{removed} = '';
+ $change->{added} = $change->{added} ? 'true' : 'false';
+ }
+
+ my $field_obj;
+ if ($change->{fieldname} =~ /^cf_/) {
+ $field_obj = Bugzilla::Field->new({name => $change->{fieldname}, cache => 1});
+ $change->{fieldtype} = $field_obj->type;
+ }
+
+ # identify buglist changes
+ if ( $change->{fieldname} eq 'blocked'
+ || $change->{fieldname} eq 'dependson'
+ || $change->{fieldname} eq 'dupe'
+ || ($field_obj && $field_obj->type == FIELD_TYPE_BUG_ID))
+ {
+ $change->{buglist} = 1;
+ foreach my $what (qw(removed added)) {
+ my @buglist = split(/[\s,]+/, $change->{$what});
+ foreach my $id (@buglist) {
+ if ($id && $id =~ /^\d+$/) {
+ $visible_bug_ids{$id} = 1;
}
+ }
+ }
+ }
+
+ # split see-also
+ if ($change->{fieldname} eq 'see_also') {
+ my $url_base = Bugzilla->localconfig->{urlbase};
+ foreach my $f (qw( added removed )) {
+ my @values;
+ foreach my $value (split(/, /, $change->{$f})) {
+ my ($bug_id)
+ = substr($value, 0, length($url_base)) eq $url_base
+ ? $value =~ /id=(\d+)$/
+ : undef;
+ push @values, {url => $value, bug_id => $bug_id,};
+ }
+ $change->{$f} = \@values;
+ }
+ }
+
+ # split multiple flag changes (must be processed last)
+ if ($change->{fieldname} eq 'flagtypes.name') {
+ my @added = split(/, /, $change->{added});
+ my @removed = split(/, /, $change->{removed});
+ next if scalar(@added) <= 1 && scalar(@removed) <= 1;
+
+ # remove current change
+ splice(@{$operation->{changes}}, $i, 1);
+
+ # restructure into added/removed for each flag
+ my %flags;
+ foreach my $added (@added) {
+ my ($value, $name) = $added =~ /^((.+).)$/;
+ next unless defined $name;
+ $flags{$name}{added} = $value;
+ $flags{$name}{removed} |= '';
+ }
+ foreach my $removed (@removed) {
+ my ($value, $name) = $removed =~ /^((.+).)$/;
+ next unless defined $name;
+ $flags{$name}{added} |= '';
+ $flags{$name}{removed} = $value;
+ }
- # split multiple flag changes (must be processed last)
- if ($change->{fieldname} eq 'flagtypes.name') {
- my @added = split(/, /, $change->{added});
- my @removed = split(/, /, $change->{removed});
- next if scalar(@added) <= 1 && scalar(@removed) <= 1;
- # remove current change
- splice(@{$operation->{changes}}, $i, 1);
- # restructure into added/removed for each flag
- my %flags;
- foreach my $added (@added) {
- my ($value, $name) = $added =~ /^((.+).)$/;
- next unless defined $name;
- $flags{$name}{added} = $value;
- $flags{$name}{removed} |= '';
- }
- foreach my $removed (@removed) {
- my ($value, $name) = $removed =~ /^((.+).)$/;
- next unless defined $name;
- $flags{$name}{added} |= '';
- $flags{$name}{removed} = $value;
- }
- # clone current change, modify and insert
- foreach my $flag (sort keys %flags) {
- my $flag_change = {};
- foreach my $key (keys %$change) {
- $flag_change->{$key} = $change->{$key};
- }
- $flag_change->{removed} = $flags{$flag}{removed};
- $flag_change->{added} = $flags{$flag}{added};
- splice(@{$operation->{changes}}, $i, 0, $flag_change);
- }
- $i--;
- }
+ # clone current change, modify and insert
+ foreach my $flag (sort keys %flags) {
+ my $flag_change = {};
+ foreach my $key (keys %$change) {
+ $flag_change->{$key} = $change->{$key};
+ }
+ $flag_change->{removed} = $flags{$flag}{removed};
+ $flag_change->{added} = $flags{$flag}{added};
+ splice(@{$operation->{changes}}, $i, 0, $flag_change);
}
+ $i--;
+ }
}
+ }
- $user->visible_bugs([keys %visible_bug_ids]);
+ $user->visible_bugs([keys %visible_bug_ids]);
- $vars->{'ih_activity'} = $activity;
+ $vars->{'ih_activity'} = $activity;
}
sub _add_duplicates {
- # insert 'is a dupe of this bug' comment to allow js to display
- # as activity
- my ($bug_id, $activity) = @_;
+ # insert 'is a dupe of this bug' comment to allow js to display
+ # as activity
- # we're ignoring pre-bugzilla 3.0 ".. has been marked as a duplicate .."
- # comments because searching each comment's text is expensive. these
- # legacy comments will not be visible at all in the bug's comment/activity
- # stream. bug 928786 deals with migrating those comments to be stored as
- # CMT_HAS_DUPE instead.
+ my ($bug_id, $activity) = @_;
- my $dbh = Bugzilla->dbh;
- my $sth = $dbh->prepare("
- SELECT profiles.login_name, " .
- $dbh->sql_date_format('bug_when', '%Y.%m.%d %H:%i:%s') . ",
+ # we're ignoring pre-bugzilla 3.0 ".. has been marked as a duplicate .."
+ # comments because searching each comment's text is expensive. these
+ # legacy comments will not be visible at all in the bug's comment/activity
+ # stream. bug 928786 deals with migrating those comments to be stored as
+ # CMT_HAS_DUPE instead.
+
+ my $dbh = Bugzilla->dbh;
+ my $sth = $dbh->prepare("
+ SELECT profiles.login_name, "
+ . $dbh->sql_date_format('bug_when', '%Y.%m.%d %H:%i:%s') . ",
extra_data
FROM longdescs
INNER JOIN profiles ON profiles.userid = longdescs.who
WHERE bug_id = ? AND type = ?
ORDER BY bug_when
");
- $sth->execute($bug_id, CMT_HAS_DUPE);
-
- while (my($who, $when, $dupe_id) = $sth->fetchrow_array) {
- my $entry = {
- 'when' => $when,
- 'who' => $who,
- 'changes' => [
- {
- 'removed' => '',
- 'added' => $dupe_id,
- 'attachid' => undef,
- 'fieldname' => 'dupe',
- 'dupe' => 1,
- }
- ],
- };
- push @$activity, $entry;
- }
+ $sth->execute($bug_id, CMT_HAS_DUPE);
+
+ while (my ($who, $when, $dupe_id) = $sth->fetchrow_array) {
+ my $entry = {
+ 'when' => $when,
+ 'who' => $who,
+ 'changes' => [{
+ 'removed' => '',
+ 'added' => $dupe_id,
+ 'attachid' => undef,
+ 'fieldname' => 'dupe',
+ 'dupe' => 1,
+ }],
+ };
+ push @$activity, $entry;
+ }
- return [ sort { $a->{when} cmp $b->{when} } @$activity ];
+ return [sort { $a->{when} cmp $b->{when} } @$activity];
}
sub install_before_final_checks {
- my ($self, $args) = @_;
- add_setting({
- name => 'inline_history',
- options => ['on', 'off'],
- default => 'off',
- category => 'Bug Editing'
- });
+ my ($self, $args) = @_;
+ add_setting({
+ name => 'inline_history',
+ options => ['on', 'off'],
+ default => 'off',
+ category => 'Bug Editing'
+ });
}
__PACKAGE__->NAME;