summaryrefslogtreecommitdiffstats
path: root/extensions/MyDashboard
diff options
context:
space:
mode:
Diffstat (limited to 'extensions/MyDashboard')
-rw-r--r--extensions/MyDashboard/Extension.pm317
-rw-r--r--extensions/MyDashboard/lib/BugInterest.pm54
-rw-r--r--extensions/MyDashboard/lib/Queries.pm566
-rw-r--r--extensions/MyDashboard/lib/Util.pm32
-rw-r--r--extensions/MyDashboard/lib/WebService.pm220
5 files changed, 602 insertions, 587 deletions
diff --git a/extensions/MyDashboard/Extension.pm b/extensions/MyDashboard/Extension.pm
index fc3a689bf..ae7921af7 100644
--- a/extensions/MyDashboard/Extension.pm
+++ b/extensions/MyDashboard/Extension.pm
@@ -29,54 +29,53 @@ our $VERSION = BUGZILLA_VERSION;
################
sub db_schema_abstract_schema {
- my ($self, $args) = @_;
-
- my $schema = $args->{schema};
-
- $schema->{'mydashboard'} = {
- FIELDS => [
- namedquery_id => {TYPE => 'INT3', NOTNULL => 1,
- REFERENCES => {TABLE => 'namedqueries',
- COLUMN => 'id',
- DELETE => 'CASCADE'}},
- user_id => {TYPE => 'INT3', NOTNULL => 1,
- REFERENCES => {TABLE => 'profiles',
- COLUMN => 'userid',
- DELETE => 'CASCADE'}},
- ],
- INDEXES => [
- mydashboard_namedquery_id_idx => {FIELDS => [qw(namedquery_id user_id)],
- TYPE => 'UNIQUE'},
- mydashboard_user_id_idx => ['user_id'],
- ],
- };
-
- $schema->{'bug_interest'} = {
- FIELDS => [
- id => { TYPE => 'MEDIUMSERIAL',
- NOTNULL => 1,
- PRIMARYKEY => 1 },
-
- bug_id => { TYPE => 'INT3',
- NOTNULL => 1,
- REFERENCES => { TABLE => 'bugs',
- COLUMN => 'bug_id',
- DELETE => 'CASCADE' } },
-
- user_id => { TYPE => 'INT3',
- NOTNOLL => 1,
- REFERENCES => { TABLE => 'profiles',
- COLUMN => 'userid' } },
-
- modification_time => { TYPE => 'DATETIME',
- NOTNULL => 1 }
- ],
- INDEXES => [
- bug_interest_idx => { FIELDS => [qw(bug_id user_id)],
- TYPE => 'UNIQUE' },
- bug_interest_user_id_idx => ['user_id']
- ],
- };
+ my ($self, $args) = @_;
+
+ my $schema = $args->{schema};
+
+ $schema->{'mydashboard'} = {
+ FIELDS => [
+ namedquery_id => {
+ TYPE => 'INT3',
+ NOTNULL => 1,
+ REFERENCES => {TABLE => 'namedqueries', COLUMN => 'id', DELETE => 'CASCADE'}
+ },
+ user_id => {
+ TYPE => 'INT3',
+ NOTNULL => 1,
+ REFERENCES => {TABLE => 'profiles', COLUMN => 'userid', DELETE => 'CASCADE'}
+ },
+ ],
+ INDEXES => [
+ mydashboard_namedquery_id_idx =>
+ {FIELDS => [qw(namedquery_id user_id)], TYPE => 'UNIQUE'},
+ mydashboard_user_id_idx => ['user_id'],
+ ],
+ };
+
+ $schema->{'bug_interest'} = {
+ FIELDS => [
+ id => {TYPE => 'MEDIUMSERIAL', NOTNULL => 1, PRIMARYKEY => 1},
+
+ bug_id => {
+ TYPE => 'INT3',
+ NOTNULL => 1,
+ REFERENCES => {TABLE => 'bugs', COLUMN => 'bug_id', DELETE => 'CASCADE'}
+ },
+
+ user_id => {
+ TYPE => 'INT3',
+ NOTNOLL => 1,
+ REFERENCES => {TABLE => 'profiles', COLUMN => 'userid'}
+ },
+
+ modification_time => {TYPE => 'DATETIME', NOTNULL => 1}
+ ],
+ INDEXES => [
+ bug_interest_idx => {FIELDS => [qw(bug_id user_id)], TYPE => 'UNIQUE'},
+ bug_interest_user_id_idx => ['user_id']
+ ],
+ };
}
###########
@@ -84,34 +83,35 @@ sub db_schema_abstract_schema {
###########
BEGIN {
- *Bugzilla::Search::Saved::in_mydashboard = \&_in_mydashboard;
- *Bugzilla::Component::watcher_ids = \&_component_watcher_ids;
+ *Bugzilla::Search::Saved::in_mydashboard = \&_in_mydashboard;
+ *Bugzilla::Component::watcher_ids = \&_component_watcher_ids;
}
sub _in_mydashboard {
- my ($self) = @_;
- my $dbh = Bugzilla->dbh;
- return $self->{'in_mydashboard'} if exists $self->{'in_mydashboard'};
- $self->{'in_mydashboard'} = $dbh->selectrow_array("
- SELECT 1 FROM mydashboard WHERE namedquery_id = ? AND user_id = ?",
- undef, $self->id, Bugzilla->user->id);
- return $self->{'in_mydashboard'};
+ my ($self) = @_;
+ my $dbh = Bugzilla->dbh;
+ return $self->{'in_mydashboard'} if exists $self->{'in_mydashboard'};
+ $self->{'in_mydashboard'} = $dbh->selectrow_array("
+ SELECT 1 FROM mydashboard WHERE namedquery_id = ? AND user_id = ?", undef,
+ $self->id, Bugzilla->user->id);
+ return $self->{'in_mydashboard'};
}
sub _component_watcher_ids {
- my ($self) = @_;
- my $dbh = Bugzilla->dbh;
+ my ($self) = @_;
+ my $dbh = Bugzilla->dbh;
- my $query = "SELECT user_id FROM component_watch
+ my $query = "SELECT user_id FROM component_watch
WHERE product_id = ?
AND (component_id = ?
OR component_id IS NULL
OR ? LIKE @{[$dbh->sql_string_concat('component_prefix', q{'%'})]})";
- $self->{watcher_ids} ||= $dbh->selectcol_arrayref($query, undef,
- $self->product_id, $self->id, $self->name);
+ $self->{watcher_ids}
+ ||= $dbh->selectcol_arrayref($query, undef, $self->product_id, $self->id,
+ $self->name);
- return $self->{watcher_ids};
+ return $self->{watcher_ids};
}
#############
@@ -119,16 +119,16 @@ sub _component_watcher_ids {
#############
sub page_before_template {
- my ($self, $args) = @_;
- my $page = $args->{'page_id'};
- my $vars = $args->{'vars'};
+ my ($self, $args) = @_;
+ my $page = $args->{'page_id'};
+ my $vars = $args->{'vars'};
- return if $page ne 'mydashboard.html';
+ return if $page ne 'mydashboard.html';
- # require user to be logged in for this page
- Bugzilla->login(LOGIN_REQUIRED);
+ # require user to be logged in for this page
+ Bugzilla->login(LOGIN_REQUIRED);
- $vars->{queries} = [ QUERY_DEFS ];
+ $vars->{queries} = [QUERY_DEFS];
}
#########
@@ -136,115 +136,122 @@ sub page_before_template {
#########
sub user_preferences {
- my ($self, $args) = @_;
- my $tab = $args->{'current_tab'};
- return unless $tab eq 'saved-searches';
+ my ($self, $args) = @_;
+ my $tab = $args->{'current_tab'};
+ return unless $tab eq 'saved-searches';
- my $save = $args->{'save_changes'};
- my $handled = $args->{'handled'};
- my $vars = $args->{'vars'};
+ my $save = $args->{'save_changes'};
+ my $handled = $args->{'handled'};
+ my $vars = $args->{'vars'};
- my $dbh = Bugzilla->dbh;
- my $user = Bugzilla->user;
- my $params = Bugzilla->input_params;
+ my $dbh = Bugzilla->dbh;
+ my $user = Bugzilla->user;
+ my $params = Bugzilla->input_params;
- if ($save) {
- my $sth_insert_fp = $dbh->prepare('INSERT INTO mydashboard
+ if ($save) {
+ my $sth_insert_fp = $dbh->prepare(
+ 'INSERT INTO mydashboard
(namedquery_id, user_id)
- VALUES (?, ?)');
- my $sth_delete_fp = $dbh->prepare('DELETE FROM mydashboard
+ VALUES (?, ?)'
+ );
+ my $sth_delete_fp = $dbh->prepare(
+ 'DELETE FROM mydashboard
WHERE namedquery_id = ?
- AND user_id = ?');
- foreach my $q (@{$user->queries}) {
- if (defined $params->{'in_mydashboard_' . $q->id}) {
- $sth_insert_fp->execute($q->id, $user->id) if !$q->in_mydashboard;
- }
- else {
- $sth_delete_fp->execute($q->id, $user->id) if $q->in_mydashboard;
- }
- }
+ AND user_id = ?'
+ );
+ foreach my $q (@{$user->queries}) {
+ if (defined $params->{'in_mydashboard_' . $q->id}) {
+ $sth_insert_fp->execute($q->id, $user->id) if !$q->in_mydashboard;
+ }
+ else {
+ $sth_delete_fp->execute($q->id, $user->id) if $q->in_mydashboard;
+ }
}
+ }
}
sub webservice {
- my ($self, $args) = @_;
- my $dispatch = $args->{dispatch};
- $dispatch->{MyDashboard} = "Bugzilla::Extension::MyDashboard::WebService";
+ my ($self, $args) = @_;
+ my $dispatch = $args->{dispatch};
+ $dispatch->{MyDashboard} = "Bugzilla::Extension::MyDashboard::WebService";
}
sub bug_end_of_create {
- my ($self, $args) = @_;
- my ($bug, $params, $timestamp) = @$args{qw(bug params timestamp)};
- my $user = Bugzilla->user;
-
- # Anyone added to the CC list of a bug is now interested in that bug.
- foreach my $cc_user (@{ $bug->cc_users }) {
- next if $user->id == $cc_user->id;
- Bugzilla::Extension::MyDashboard::BugInterest->mark($cc_user->id, $bug->id, $timestamp);
- }
-
- # Anyone that is watching a component is interested when a bug is filed into the component.
- foreach my $watcher_id (@{ $bug->component_obj->watcher_ids }) {
- Bugzilla::Extension::MyDashboard::BugInterest->mark($watcher_id, $bug->id, $timestamp);
- }
+ my ($self, $args) = @_;
+ my ($bug, $params, $timestamp) = @$args{qw(bug params timestamp)};
+ my $user = Bugzilla->user;
+
+ # Anyone added to the CC list of a bug is now interested in that bug.
+ foreach my $cc_user (@{$bug->cc_users}) {
+ next if $user->id == $cc_user->id;
+ Bugzilla::Extension::MyDashboard::BugInterest->mark($cc_user->id, $bug->id,
+ $timestamp);
+ }
+
+# Anyone that is watching a component is interested when a bug is filed into the component.
+ foreach my $watcher_id (@{$bug->component_obj->watcher_ids}) {
+ Bugzilla::Extension::MyDashboard::BugInterest->mark($watcher_id, $bug->id,
+ $timestamp);
+ }
}
sub bug_end_of_update {
- my ($self, $args) = @_;
- my ($bug, $old_bug, $changes, $timestamp) = @$args{qw(bug old_bug changes timestamp)};
- my $user = Bugzilla->user;
-
- # Anyone added to the CC list of a bug is now interested in that bug.
- my %old_cc = map { $_->id => $_ } grep { defined } @{ $old_bug->cc_users };
- my @added = grep { not $old_cc{ $_->id } } grep { defined } @{ $bug->cc_users };
- foreach my $cc_user (@added) {
- next if $user->id == $cc_user->id;
- Bugzilla::Extension::MyDashboard::BugInterest->mark($cc_user->id, $bug->id, $timestamp);
+ my ($self, $args) = @_;
+ my ($bug, $old_bug, $changes, $timestamp)
+ = @$args{qw(bug old_bug changes timestamp)};
+ my $user = Bugzilla->user;
+
+ # Anyone added to the CC list of a bug is now interested in that bug.
+ my %old_cc = map { $_->id => $_ } grep {defined} @{$old_bug->cc_users};
+ my @added = grep { not $old_cc{$_->id} } grep {defined} @{$bug->cc_users};
+ foreach my $cc_user (@added) {
+ next if $user->id == $cc_user->id;
+ Bugzilla::Extension::MyDashboard::BugInterest->mark($cc_user->id, $bug->id,
+ $timestamp);
+ }
+
+# Anyone that is watching a component is interested when a bug is filed into the component.
+ if ($changes->{product} or $changes->{component}) {
+
+ # All of the watchers would be interested in this bug update
+ foreach my $watcher_id (@{$bug->component_obj->watcher_ids}) {
+ Bugzilla::Extension::MyDashboard::BugInterest->mark($watcher_id, $bug->id,
+ $timestamp);
}
+ }
- # Anyone that is watching a component is interested when a bug is filed into the component.
- if ($changes->{product} or $changes->{component}) {
- # All of the watchers would be interested in this bug update
- foreach my $watcher_id (@{ $bug->component_obj->watcher_ids }) {
- Bugzilla::Extension::MyDashboard::BugInterest->mark($watcher_id, $bug->id, $timestamp);
- }
- }
+ if ($changes->{bug_status}) {
+ my ($old_status, $new_status) = @{$changes->{bug_status}};
+ if (is_open_state($old_status) && !is_open_state($new_status)) {
+ my @related_bugs = (@{$bug->blocks_obj}, @{$bug->depends_on_obj});
+ my %involved;
- if ($changes->{bug_status}) {
- my ($old_status, $new_status) = @{ $changes->{bug_status} };
- if (is_open_state($old_status) && !is_open_state($new_status)) {
- my @related_bugs = (@{ $bug->blocks_obj }, @{ $bug->depends_on_obj });
- my %involved;
-
- foreach my $related_bug (@related_bugs) {
- my @users = grep { defined } $related_bug->assigned_to,
- $related_bug->reporter,
- $related_bug->qa_contact,
- @{ $related_bug->cc_users };
-
- foreach my $involved_user (@users) {
- $involved{ $involved_user->id }{ $related_bug->id } = 1;
- }
- }
- foreach my $involved_user_id (keys %involved) {
- foreach my $related_bug_id (keys %{$involved{$involved_user_id}}) {
- Bugzilla::Extension::MyDashboard::BugInterest->mark($involved_user_id,
- $related_bug_id,
- $timestamp);
- }
- }
+ foreach my $related_bug (@related_bugs) {
+ my @users = grep {defined} $related_bug->assigned_to, $related_bug->reporter,
+ $related_bug->qa_contact, @{$related_bug->cc_users};
+
+ foreach my $involved_user (@users) {
+ $involved{$involved_user->id}{$related_bug->id} = 1;
+ }
+ }
+ foreach my $involved_user_id (keys %involved) {
+ foreach my $related_bug_id (keys %{$involved{$involved_user_id}}) {
+ Bugzilla::Extension::MyDashboard::BugInterest->mark($involved_user_id,
+ $related_bug_id, $timestamp);
}
+ }
}
+ }
}
sub merge_users_before {
- my ($self, $args) = @_;
- my $old_id = $args->{old_id};
- my $dbh = Bugzilla->dbh;
+ my ($self, $args) = @_;
+ my $old_id = $args->{old_id};
+ my $dbh = Bugzilla->dbh;
- # If the bug_interest table has both the source user
- # and destination user, then we remove the old user entry.
- $dbh->do("DELETE FROM bug_interest WHERE user_id = ?", undef, $old_id);
+ # If the bug_interest table has both the source user
+ # and destination user, then we remove the old user entry.
+ $dbh->do("DELETE FROM bug_interest WHERE user_id = ?", undef, $old_id);
}
__PACKAGE__->NAME;
diff --git a/extensions/MyDashboard/lib/BugInterest.pm b/extensions/MyDashboard/lib/BugInterest.pm
index cf33900c5..2e427d612 100644
--- a/extensions/MyDashboard/lib/BugInterest.pm
+++ b/extensions/MyDashboard/lib/BugInterest.pm
@@ -25,47 +25,45 @@ use constant LIST_ORDER => 'id';
use constant NAME_FIELD => 'id';
# turn off auditing and exclude these objects from memcached
-use constant { AUDIT_CREATES => 0,
- AUDIT_UPDATES => 0,
- AUDIT_REMOVES => 0,
- USE_MEMCACHED => 0 };
+use constant {
+ AUDIT_CREATES => 0,
+ AUDIT_UPDATES => 0,
+ AUDIT_REMOVES => 0,
+ USE_MEMCACHED => 0
+};
#####################################################################
# Provide accessors for our columns
#####################################################################
-sub id { return $_[0]->{id} }
-sub bug_id { return $_[0]->{bug_id} }
-sub user_id { return $_[0]->{user_id} }
+sub id { return $_[0]->{id} }
+sub bug_id { return $_[0]->{bug_id} }
+sub user_id { return $_[0]->{user_id} }
sub modification_time { return $_[0]->{modification_time} }
sub mark {
- my ($class, $user_id, $bug_id, $timestamp) = @_;
+ my ($class, $user_id, $bug_id, $timestamp) = @_;
- my ($interest) = @{ $class->match({ user_id => $user_id,
- bug_id => $bug_id }) };
- if ($interest) {
- $interest->set(modification_time => $timestamp);
- $interest->update();
- return $interest;
- }
- else {
- return $class->create({
- user_id => $user_id,
- bug_id => $bug_id,
- modification_time => $timestamp,
- });
- }
+ my ($interest) = @{$class->match({user_id => $user_id, bug_id => $bug_id})};
+ if ($interest) {
+ $interest->set(modification_time => $timestamp);
+ $interest->update();
+ return $interest;
+ }
+ else {
+ return $class->create({
+ user_id => $user_id, bug_id => $bug_id, modification_time => $timestamp,
+ });
+ }
}
sub unmark {
- my ($class, $user_id, $bug_id) = @_;
+ my ($class, $user_id, $bug_id) = @_;
- my ($interest) = @{ $class->match({ user_id => $user_id,
- bug_id => $bug_id }) };
- if ($interest) {
- $interest->remove_from_db();
- }
+ my ($interest) = @{$class->match({user_id => $user_id, bug_id => $bug_id})};
+ if ($interest) {
+ $interest->remove_from_db();
+ }
}
1;
diff --git a/extensions/MyDashboard/lib/Queries.pm b/extensions/MyDashboard/lib/Queries.pm
index d77be7da4..59cb4f14e 100644
--- a/extensions/MyDashboard/lib/Queries.pm
+++ b/extensions/MyDashboard/lib/Queries.pm
@@ -25,11 +25,11 @@ use DateTime;
use base qw(Exporter);
our @EXPORT = qw(
- QUERY_ORDER
- SELECT_COLUMNS
- QUERY_DEFS
- query_bugs
- query_flags
+ QUERY_ORDER
+ SELECT_COLUMNS
+ QUERY_DEFS
+ query_bugs
+ query_flags
);
# Default sort order
@@ -38,294 +38,300 @@ use constant QUERY_ORDER => ("changeddate desc", "bug_id");
# List of columns that we will be selecting. In the future this should be configurable
# Share with buglist.cgi?
use constant SELECT_COLUMNS => qw(
- bug_id
- bug_status
- short_desc
- changeddate
+ bug_id
+ bug_status
+ short_desc
+ changeddate
);
sub QUERY_DEFS {
- my $user = Bugzilla->user;
-
- my @query_defs = (
- {
- name => 'assignedbugs',
- heading => 'Assigned to You',
- description => 'The bug has been assigned to you, and it is not resolved or closed.',
- params => {
- 'bug_status' => ['__open__'],
- 'emailassigned_to1' => 1,
- 'emailtype1' => 'exact',
- 'email1' => $user->login
- }
- },
- {
- name => 'newbugs',
- heading => 'New Reported by You',
- description => 'You reported the bug; it\'s unconfirmed or new. No one has assigned themselves to fix it yet.',
- params => {
- 'bug_status' => ['UNCONFIRMED', 'NEW'],
- 'emailreporter1' => 1,
- 'emailtype1' => 'exact',
- 'email1' => $user->login
- }
- },
- {
- name => 'inprogressbugs',
- heading => "In Progress Reported by You",
- description => 'A developer accepted your bug and is working on it. (It has someone in the "Assigned to" field.)',
- params => {
- 'bug_status' => [ map { $_->name } grep($_->name ne 'UNCONFIRMED' && $_->name ne 'NEW', open_states()) ],
- 'emailreporter1' => 1,
- 'emailtype1' => 'exact',
- 'email1' => $user->login
- }
- },
- {
- name => 'openccbugs',
- heading => "You Are CC'd On",
- description => 'You are in the CC list of the bug, so you are watching it.',
- params => {
- 'bug_status' => ['__open__'],
- 'emailcc1' => 1,
- 'emailtype1' => 'exact',
- 'email1' => $user->login
- }
- },
- {
- name => 'mentorbugs',
- heading => "You Are a Mentor",
- description => 'You are one of the mentors for the bug.',
- params => {
- 'bug_status' => ['__open__'],
- 'emailbug_mentor1' => 1,
- 'emailtype1' => 'exact',
- 'email1' => $user->login
- }
- },
- {
- name => 'lastvisitedbugs',
- heading => 'Updated Since Last Visit',
- description => 'Bugs updated since last visited',
- mark_read => 'Mark Visited',
- params => {
- o1 => 'lessthan',
- v1 => '%last_changed%',
- f1 => 'last_visit_ts',
- },
- },
- {
- name => 'interestingbugs',
- heading => 'Interesting Bugs',
- description => 'Bugs that you may find interesting',
- mark_read => 'Remove Interest',
- params => {
- j_top => 'OR',
- f1 => 'bug_interest_ts',
- o1 => 'isnotempty',
-
- f2 => 'last_visit_ts',
- o2 => 'lessthan',
- v2 => '%last_changed%',
- }
- },
- {
- name => 'nevervisitbugs',
- heading => 'Involved with and Never Visited',
- description => "Bugs you've never visited, but are involved with",
- mark_read => 'Mark Visited',
- params => {
- query_format => "advanced",
- bug_status => ['__open__'],,
- o1 => "isempty",
- f1 => "last_visit_ts",
- j2 => "OR",
- f2 => "OP",
- f3 => "assigned_to",
- o3 => "equals",
- v3 => $user->login,
- o4 => "equals",
- f4 => "reporter",
- v4 => $user->login,
- v5 => $user->login,
- f5 => "qa_contact",
- o5 => "equals",
- o6 => "equals",
- f6 => "cc",
- v6 => $user->login,
- f7 => "bug_mentor",
- o7 => "equals",
- v7 => $user->login,
- f9 => "CP",
- },
- },
+ my $user = Bugzilla->user;
+
+ my @query_defs = (
+ {
+ name => 'assignedbugs',
+ heading => 'Assigned to You',
+ description =>
+ 'The bug has been assigned to you, and it is not resolved or closed.',
+ params => {
+ 'bug_status' => ['__open__'],
+ 'emailassigned_to1' => 1,
+ 'emailtype1' => 'exact',
+ 'email1' => $user->login
+ }
+ },
+ {
+ name => 'newbugs',
+ heading => 'New Reported by You',
+ description =>
+ 'You reported the bug; it\'s unconfirmed or new. No one has assigned themselves to fix it yet.',
+ params => {
+ 'bug_status' => ['UNCONFIRMED', 'NEW'],
+ 'emailreporter1' => 1,
+ 'emailtype1' => 'exact',
+ 'email1' => $user->login
+ }
+ },
+ {
+ name => 'inprogressbugs',
+ heading => "In Progress Reported by You",
+ description =>
+ 'A developer accepted your bug and is working on it. (It has someone in the "Assigned to" field.)',
+ params => {
+ 'bug_status' => [
+ map { $_->name }
+ grep($_->name ne 'UNCONFIRMED' && $_->name ne 'NEW', open_states())
+ ],
+ 'emailreporter1' => 1,
+ 'emailtype1' => 'exact',
+ 'email1' => $user->login
+ }
+ },
+ {
+ name => 'openccbugs',
+ heading => "You Are CC'd On",
+ description => 'You are in the CC list of the bug, so you are watching it.',
+ params => {
+ 'bug_status' => ['__open__'],
+ 'emailcc1' => 1,
+ 'emailtype1' => 'exact',
+ 'email1' => $user->login
+ }
+ },
+ {
+ name => 'mentorbugs',
+ heading => "You Are a Mentor",
+ description => 'You are one of the mentors for the bug.',
+ params => {
+ 'bug_status' => ['__open__'],
+ 'emailbug_mentor1' => 1,
+ 'emailtype1' => 'exact',
+ 'email1' => $user->login
+ }
+ },
+ {
+ name => 'lastvisitedbugs',
+ heading => 'Updated Since Last Visit',
+ description => 'Bugs updated since last visited',
+ mark_read => 'Mark Visited',
+ params => {o1 => 'lessthan', v1 => '%last_changed%', f1 => 'last_visit_ts',},
+ },
+ {
+ name => 'interestingbugs',
+ heading => 'Interesting Bugs',
+ description => 'Bugs that you may find interesting',
+ mark_read => 'Remove Interest',
+ params => {
+ j_top => 'OR',
+ f1 => 'bug_interest_ts',
+ o1 => 'isnotempty',
+
+ f2 => 'last_visit_ts',
+ o2 => 'lessthan',
+ v2 => '%last_changed%',
+ }
+ },
+ {
+ name => 'nevervisitbugs',
+ heading => 'Involved with and Never Visited',
+ description => "Bugs you've never visited, but are involved with",
+ mark_read => 'Mark Visited',
+ params => {
+ query_format => "advanced",
+ bug_status => ['__open__'],
+ ,
+ o1 => "isempty",
+ f1 => "last_visit_ts",
+ j2 => "OR",
+ f2 => "OP",
+ f3 => "assigned_to",
+ o3 => "equals",
+ v3 => $user->login,
+ o4 => "equals",
+ f4 => "reporter",
+ v4 => $user->login,
+ v5 => $user->login,
+ f5 => "qa_contact",
+ o5 => "equals",
+ o6 => "equals",
+ f6 => "cc",
+ v6 => $user->login,
+ f7 => "bug_mentor",
+ o7 => "equals",
+ v7 => $user->login,
+ f9 => "CP",
+ },
+ },
+ );
+
+ if (Bugzilla->params->{'useqacontact'}) {
+ push(
+ @query_defs,
+ {
+ name => 'qacontactbugs',
+ heading => 'You Are QA Contact',
+ description =>
+ 'You are the qa contact on this bug, and it is not resolved or closed.',
+ params => {
+ 'bug_status' => ['__open__'],
+ 'emailqa_contact1' => 1,
+ 'emailtype1' => 'exact',
+ 'email1' => $user->login
+ }
+ }
);
-
- if (Bugzilla->params->{'useqacontact'}) {
- push(@query_defs, {
- name => 'qacontactbugs',
- heading => 'You Are QA Contact',
- description => 'You are the qa contact on this bug, and it is not resolved or closed.',
- params => {
- 'bug_status' => ['__open__'],
- 'emailqa_contact1' => 1,
- 'emailtype1' => 'exact',
- 'email1' => $user->login
- }
- });
- }
-
- if ($user->showmybugslink) {
- my $query = Bugzilla->params->{mybugstemplate};
- my $login = $user->login;
- $query =~ s/%userid%/$login/;
- $query =~ s/^buglist.cgi\?//;
- push(@query_defs, {
- name => 'mybugs',
- heading => "My Bugs",
- saved => 1,
- params => $query,
- });
- }
-
- foreach my $q (@{$user->queries}) {
- next if !$q->in_mydashboard;
- push(@query_defs, { name => $q->name,
- saved => 1,
- params => $q->url });
- }
-
- return @query_defs;
+ }
+
+ if ($user->showmybugslink) {
+ my $query = Bugzilla->params->{mybugstemplate};
+ my $login = $user->login;
+ $query =~ s/%userid%/$login/;
+ $query =~ s/^buglist.cgi\?//;
+ push(@query_defs,
+ {name => 'mybugs', heading => "My Bugs", saved => 1, params => $query,});
+ }
+
+ foreach my $q (@{$user->queries}) {
+ next if !$q->in_mydashboard;
+ push(@query_defs, {name => $q->name, saved => 1, params => $q->url});
+ }
+
+ return @query_defs;
}
sub query_bugs {
- my $qdef = shift;
- my $dbh = Bugzilla->dbh;
- my $user = Bugzilla->user;
- my $datetime_now = DateTime->now(time_zone => $user->timezone);
-
- ## HACK to remove POST
- delete $ENV{REQUEST_METHOD};
-
- my $params = new Bugzilla::CGI($qdef->{params});
-
- my $search = new Bugzilla::Search( fields => [ SELECT_COLUMNS ],
- params => scalar $params->Vars,
- order => [ QUERY_ORDER ]);
- my $data = $search->data;
-
- my @bugs;
- foreach my $row (@$data) {
- my $bug = {};
- foreach my $column (SELECT_COLUMNS) {
- $bug->{$column} = shift @$row;
- if ($column eq 'changeddate') {
- my $datetime = datetime_from($bug->{$column});
- $datetime->set_time_zone($user->timezone);
- $bug->{$column} = $datetime->strftime('%Y-%m-%d %T %Z');
- $bug->{'changeddate_fancy'} = time_ago($datetime, $datetime_now);
-
- # Provide a version for use by Bug.history and also for looking up last comment.
- # We have to set to server's timezone and also subtract one second.
- $datetime->set_time_zone(Bugzilla->local_timezone);
- $datetime->subtract(seconds => 1);
- $bug->{changeddate_api} = $datetime->strftime('%Y-%m-%d %T');
- }
- }
- push(@bugs, $bug);
+ my $qdef = shift;
+ my $dbh = Bugzilla->dbh;
+ my $user = Bugzilla->user;
+ my $datetime_now = DateTime->now(time_zone => $user->timezone);
+
+ ## HACK to remove POST
+ delete $ENV{REQUEST_METHOD};
+
+ my $params = new Bugzilla::CGI($qdef->{params});
+
+ my $search = new Bugzilla::Search(
+ fields => [SELECT_COLUMNS],
+ params => scalar $params->Vars,
+ order => [QUERY_ORDER]
+ );
+ my $data = $search->data;
+
+ my @bugs;
+ foreach my $row (@$data) {
+ my $bug = {};
+ foreach my $column (SELECT_COLUMNS) {
+ $bug->{$column} = shift @$row;
+ if ($column eq 'changeddate') {
+ my $datetime = datetime_from($bug->{$column});
+ $datetime->set_time_zone($user->timezone);
+ $bug->{$column} = $datetime->strftime('%Y-%m-%d %T %Z');
+ $bug->{'changeddate_fancy'} = time_ago($datetime, $datetime_now);
+
+ # Provide a version for use by Bug.history and also for looking up last comment.
+ # We have to set to server's timezone and also subtract one second.
+ $datetime->set_time_zone(Bugzilla->local_timezone);
+ $datetime->subtract(seconds => 1);
+ $bug->{changeddate_api} = $datetime->strftime('%Y-%m-%d %T');
+ }
}
+ push(@bugs, $bug);
+ }
- return (\@bugs, $params->canonicalise_query());
+ return (\@bugs, $params->canonicalise_query());
}
sub query_flags {
- my ($type) = @_;
- my $user = Bugzilla->user;
- my $dbh = Bugzilla->dbh;
- my $datetime_now = DateTime->now(time_zone => $user->timezone);
-
- ($type ne 'requestee' || $type ne 'requester')
- || ThrowCodeError('param_required', { param => 'type' });
-
- my $match_params = { status => '?' };
-
- if ($type eq 'requestee') {
- $match_params->{'requestee_id'} = $user->id;
- }
- else {
- $match_params->{'setter_id'} = $user->id;
- }
-
- my $matched = Bugzilla::Flag->match($match_params);
-
- return [] if !@$matched;
-
- my @unfiltered_flags;
- my %all_bugs; # Use hash to filter out duplicates
- foreach my $flag (@$matched) {
- next if ($flag->attach_id && $flag->attachment->isprivate && !$user->is_insider);
-
- my $data = {
- id => $flag->id,
- type => $flag->type->name,
- status => $flag->status,
- attach_id => $flag->attach_id,
- is_patch => $flag->attach_id ? $flag->attachment->ispatch : 0,
- bug_id => $flag->bug_id,
- requester => $flag->setter->login,
- requestee => $flag->requestee ? $flag->requestee->login : '',
- updated => $flag->modification_date,
- };
- push(@unfiltered_flags, $data);
-
- # Record bug id for later retrieval of status/summary
- $all_bugs{$flag->{'bug_id'}}++;
- }
-
- # Filter the bug list based on permission to see the bug
- my %visible_bugs = map { $_ => 1 } @{ $user->visible_bugs([ keys %all_bugs ]) };
-
- return [] if !scalar keys %visible_bugs;
-
- # Get all bug statuses and summaries in one query instead of loading
- # many separate bug objects
- my $bug_rows = $dbh->selectall_arrayref("SELECT bug_id, bug_status, short_desc
+ my ($type) = @_;
+ my $user = Bugzilla->user;
+ my $dbh = Bugzilla->dbh;
+ my $datetime_now = DateTime->now(time_zone => $user->timezone);
+
+ ($type ne 'requestee' || $type ne 'requester')
+ || ThrowCodeError('param_required', {param => 'type'});
+
+ my $match_params = {status => '?'};
+
+ if ($type eq 'requestee') {
+ $match_params->{'requestee_id'} = $user->id;
+ }
+ else {
+ $match_params->{'setter_id'} = $user->id;
+ }
+
+ my $matched = Bugzilla::Flag->match($match_params);
+
+ return [] if !@$matched;
+
+ my @unfiltered_flags;
+ my %all_bugs; # Use hash to filter out duplicates
+ foreach my $flag (@$matched) {
+ next
+ if ($flag->attach_id && $flag->attachment->isprivate && !$user->is_insider);
+
+ my $data = {
+ id => $flag->id,
+ type => $flag->type->name,
+ status => $flag->status,
+ attach_id => $flag->attach_id,
+ is_patch => $flag->attach_id ? $flag->attachment->ispatch : 0,
+ bug_id => $flag->bug_id,
+ requester => $flag->setter->login,
+ requestee => $flag->requestee ? $flag->requestee->login : '',
+ updated => $flag->modification_date,
+ };
+ push(@unfiltered_flags, $data);
+
+ # Record bug id for later retrieval of status/summary
+ $all_bugs{$flag->{'bug_id'}}++;
+ }
+
+ # Filter the bug list based on permission to see the bug
+ my %visible_bugs = map { $_ => 1 } @{$user->visible_bugs([keys %all_bugs])};
+
+ return [] if !scalar keys %visible_bugs;
+
+ # Get all bug statuses and summaries in one query instead of loading
+ # many separate bug objects
+ my $bug_rows = $dbh->selectall_arrayref(
+ "SELECT bug_id, bug_status, short_desc
FROM bugs
- WHERE " . $dbh->sql_in('bug_id', [ keys %visible_bugs ]),
- { Slice => {} });
- foreach my $row (@$bug_rows) {
- $visible_bugs{$row->{'bug_id'}} = {
- bug_status => $row->{'bug_status'},
- short_desc => $row->{'short_desc'}
- };
- }
-
- # Now drop out any flags for bugs the user cannot see
- # or if the user did not want to see closed bugs
- my @filtered_flags;
- foreach my $flag (@unfiltered_flags) {
- # Skip this flag if the bug is not visible to the user
- next if !$visible_bugs{$flag->{'bug_id'}};
-
- # Include bug status and summary with each flag
- $flag->{'bug_status'} = $visible_bugs{$flag->{'bug_id'}}->{'bug_status'};
- $flag->{'bug_summary'} = $visible_bugs{$flag->{'bug_id'}}->{'short_desc'};
-
- # Format the updated date specific to the user's timezone
- # and add the fancy human readable version
- my $datetime = datetime_from($flag->{'updated'});
- $datetime->set_time_zone($user->timezone);
- $flag->{'updated'} = $datetime->strftime('%Y-%m-%d %T %Z');
- $flag->{'updated_epoch'} = $datetime->epoch;
- $flag->{'updated_fancy'} = time_ago($datetime, $datetime_now);
-
- push(@filtered_flags, $flag);
- }
-
- return [] if !@filtered_flags;
-
- # Sort by most recently updated
- return [ sort { $b->{'updated_epoch'} <=> $a->{'updated_epoch'} } @filtered_flags ];
+ WHERE "
+ . $dbh->sql_in('bug_id', [keys %visible_bugs]), {Slice => {}}
+ );
+ foreach my $row (@$bug_rows) {
+ $visible_bugs{$row->{'bug_id'}}
+ = {bug_status => $row->{'bug_status'}, short_desc => $row->{'short_desc'}};
+ }
+
+ # Now drop out any flags for bugs the user cannot see
+ # or if the user did not want to see closed bugs
+ my @filtered_flags;
+ foreach my $flag (@unfiltered_flags) {
+
+ # Skip this flag if the bug is not visible to the user
+ next if !$visible_bugs{$flag->{'bug_id'}};
+
+ # Include bug status and summary with each flag
+ $flag->{'bug_status'} = $visible_bugs{$flag->{'bug_id'}}->{'bug_status'};
+ $flag->{'bug_summary'} = $visible_bugs{$flag->{'bug_id'}}->{'short_desc'};
+
+ # Format the updated date specific to the user's timezone
+ # and add the fancy human readable version
+ my $datetime = datetime_from($flag->{'updated'});
+ $datetime->set_time_zone($user->timezone);
+ $flag->{'updated'} = $datetime->strftime('%Y-%m-%d %T %Z');
+ $flag->{'updated_epoch'} = $datetime->epoch;
+ $flag->{'updated_fancy'} = time_ago($datetime, $datetime_now);
+
+ push(@filtered_flags, $flag);
+ }
+
+ return [] if !@filtered_flags;
+
+ # Sort by most recently updated
+ return [sort { $b->{'updated_epoch'} <=> $a->{'updated_epoch'} }
+ @filtered_flags];
}
1;
diff --git a/extensions/MyDashboard/lib/Util.pm b/extensions/MyDashboard/lib/Util.pm
index 77d9505cb..f2e734b63 100644
--- a/extensions/MyDashboard/lib/Util.pm
+++ b/extensions/MyDashboard/lib/Util.pm
@@ -17,36 +17,40 @@ use Bugzilla::Status;
use base qw(Exporter);
@Bugzilla::Extension::MyDashboard::Util::EXPORT = qw(
- open_states
- closed_states
- quoted_open_states
- quoted_closed_states
+ open_states
+ closed_states
+ quoted_open_states
+ quoted_closed_states
);
our $_open_states;
+
sub open_states {
- $_open_states ||= Bugzilla::Status->match({ is_open => 1, isactive => 1 });
- return wantarray ? @$_open_states : $_open_states;
+ $_open_states ||= Bugzilla::Status->match({is_open => 1, isactive => 1});
+ return wantarray ? @$_open_states : $_open_states;
}
our $_quoted_open_states;
+
sub quoted_open_states {
- my $dbh = Bugzilla->dbh;
- $_quoted_open_states ||= [ map { $dbh->quote($_->name) } open_states() ];
- return wantarray ? @$_quoted_open_states : $_quoted_open_states;
+ my $dbh = Bugzilla->dbh;
+ $_quoted_open_states ||= [map { $dbh->quote($_->name) } open_states()];
+ return wantarray ? @$_quoted_open_states : $_quoted_open_states;
}
our $_closed_states;
+
sub closed_states {
- $_closed_states ||= Bugzilla::Status->match({ is_open => 0, isactive => 1 });
- return wantarray ? @$_closed_states : $_closed_states;
+ $_closed_states ||= Bugzilla::Status->match({is_open => 0, isactive => 1});
+ return wantarray ? @$_closed_states : $_closed_states;
}
our $_quoted_closed_states;
+
sub quoted_closed_states {
- my $dbh = Bugzilla->dbh;
- $_quoted_closed_states ||= [ map { $dbh->quote($_->name) } closed_states() ];
- return wantarray ? @$_quoted_closed_states : $_quoted_closed_states;
+ my $dbh = Bugzilla->dbh;
+ $_quoted_closed_states ||= [map { $dbh->quote($_->name) } closed_states()];
+ return wantarray ? @$_quoted_closed_states : $_quoted_closed_states;
}
1;
diff --git a/extensions/MyDashboard/lib/WebService.pm b/extensions/MyDashboard/lib/WebService.pm
index 5407c1d0b..6638bacf2 100644
--- a/extensions/MyDashboard/lib/WebService.pm
+++ b/extensions/MyDashboard/lib/WebService.pm
@@ -17,149 +17,149 @@ use Bugzilla::Error;
use Bugzilla::Util qw(detaint_natural trick_taint template_var datetime_from);
use Bugzilla::WebService::Util qw(validate);
-use Bugzilla::Extension::MyDashboard::Queries qw(QUERY_DEFS query_bugs query_flags);
+use Bugzilla::Extension::MyDashboard::Queries
+ qw(QUERY_DEFS query_bugs query_flags);
use Bugzilla::Extension::MyDashboard::BugInterest;
use constant READ_ONLY => qw(
- run_bug_query
- run_flag_query
+ run_bug_query
+ run_flag_query
);
use constant PUBLIC_METHODS => qw(
- bug_interest_unmark
- run_bug_query
- run_flag_query
- run_last_changes
+ bug_interest_unmark
+ run_bug_query
+ run_flag_query
+ run_last_changes
);
sub run_last_changes {
- my ($self, $params) = @_;
+ my ($self, $params) = @_;
- my $dbh = Bugzilla->dbh;
- my $user = Bugzilla->login(LOGIN_REQUIRED);
+ my $dbh = Bugzilla->dbh;
+ my $user = Bugzilla->login(LOGIN_REQUIRED);
- trick_taint($params->{changeddate_api});
- trick_taint($params->{bug_id});
+ trick_taint($params->{changeddate_api});
+ trick_taint($params->{bug_id});
- my $last_comment_sql = "
+ my $last_comment_sql = "
SELECT comment_id
FROM longdescs
WHERE bug_id = ? AND bug_when > ?";
- if (!$user->is_insider) {
- $last_comment_sql .= " AND isprivate = 0";
+ if (!$user->is_insider) {
+ $last_comment_sql .= " AND isprivate = 0";
+ }
+ $last_comment_sql .= " LIMIT 1";
+ my $last_comment_sth = $dbh->prepare($last_comment_sql);
+
+ my $last_changes = {};
+ my $activity
+ = $self->history({
+ ids => [$params->{bug_id}], new_since => $params->{changeddate_api}
+ });
+ if (@{$activity->{bugs}[0]{history}}) {
+ my $change_set = $activity->{bugs}[0]{history}[0];
+ $last_changes->{activity} = $change_set->{changes};
+ foreach my $change (@{$last_changes->{activity}}) {
+ $change->{field_desc} = template_var('field_descs')->{$change->{field_name}}
+ || $change->{field_name};
}
- $last_comment_sql .= " LIMIT 1";
- my $last_comment_sth = $dbh->prepare($last_comment_sql);
-
- my $last_changes = {};
- my $activity = $self->history({ ids => [ $params->{bug_id} ],
- new_since => $params->{changeddate_api} });
- if (@{$activity->{bugs}[0]{history}}) {
- my $change_set = $activity->{bugs}[0]{history}[0];
- $last_changes->{activity} = $change_set->{changes};
- foreach my $change (@{ $last_changes->{activity} }) {
- $change->{field_desc}
- = template_var('field_descs')->{$change->{field_name}} || $change->{field_name};
- }
- $last_changes->{email} = $change_set->{who};
- my $datetime = datetime_from($change_set->{when});
- $datetime->set_time_zone($user->timezone);
- $last_changes->{when} = $datetime->strftime('%Y-%m-%d %T %Z');
- }
- my $last_comment_id = $dbh->selectrow_array(
- $last_comment_sth, undef, $params->{bug_id}, $params->{changeddate_api});
- if ($last_comment_id) {
- my $comments = $self->comments({ comment_ids => [ $last_comment_id ] });
- my $comment = $comments->{comments}{$last_comment_id};
- $last_changes->{comment} = $comment->{text};
- $last_changes->{email} = $comment->{creator} if !$last_changes->{email};
- my $datetime = datetime_from($comment->{creation_time});
- $datetime->set_time_zone($user->timezone);
- $last_changes->{when} = $datetime->strftime('%Y-%m-%d %T %Z');
- }
-
- return { results => [ {last_changes => $last_changes } ] };
+ $last_changes->{email} = $change_set->{who};
+ my $datetime = datetime_from($change_set->{when});
+ $datetime->set_time_zone($user->timezone);
+ $last_changes->{when} = $datetime->strftime('%Y-%m-%d %T %Z');
+ }
+ my $last_comment_id
+ = $dbh->selectrow_array($last_comment_sth, undef, $params->{bug_id},
+ $params->{changeddate_api});
+ if ($last_comment_id) {
+ my $comments = $self->comments({comment_ids => [$last_comment_id]});
+ my $comment = $comments->{comments}{$last_comment_id};
+ $last_changes->{comment} = $comment->{text};
+ $last_changes->{email} = $comment->{creator} if !$last_changes->{email};
+ my $datetime = datetime_from($comment->{creation_time});
+ $datetime->set_time_zone($user->timezone);
+ $last_changes->{when} = $datetime->strftime('%Y-%m-%d %T %Z');
+ }
+
+ return {results => [{last_changes => $last_changes}]};
}
sub run_bug_query {
- my($self, $params) = @_;
- my $dbh = Bugzilla->dbh;
- my $user = Bugzilla->login(LOGIN_REQUIRED);
-
- defined $params->{query}
- || ThrowCodeError('param_required',
- { function => 'MyDashboard.run_bug_query',
- param => 'query' });
-
- my $result;
- foreach my $qdef (QUERY_DEFS) {
- next if $qdef->{name} ne $params->{query};
- my ($bugs, $query_string) = query_bugs($qdef);
-
- # Add last changes to each bug
- foreach my $b (@$bugs) {
- # Set the data type properly for webservice clients
- # for non-string values.
- $b->{bug_id} = $self->type('int', $b->{bug_id});
- }
-
- $query_string =~ s/^POSTDATA=&//;
- $qdef->{bugs} = $bugs;
- $qdef->{buffer} = $query_string;
- $result = $qdef;
- last;
+ my ($self, $params) = @_;
+ my $dbh = Bugzilla->dbh;
+ my $user = Bugzilla->login(LOGIN_REQUIRED);
+
+ defined $params->{query}
+ || ThrowCodeError('param_required',
+ {function => 'MyDashboard.run_bug_query', param => 'query'});
+
+ my $result;
+ foreach my $qdef (QUERY_DEFS) {
+ next if $qdef->{name} ne $params->{query};
+ my ($bugs, $query_string) = query_bugs($qdef);
+
+ # Add last changes to each bug
+ foreach my $b (@$bugs) {
+
+ # Set the data type properly for webservice clients
+ # for non-string values.
+ $b->{bug_id} = $self->type('int', $b->{bug_id});
}
- return { result => $result };
+ $query_string =~ s/^POSTDATA=&//;
+ $qdef->{bugs} = $bugs;
+ $qdef->{buffer} = $query_string;
+ $result = $qdef;
+ last;
+ }
+
+ return {result => $result};
}
sub run_flag_query {
- my ($self, $params) =@_;
- my $user = Bugzilla->login(LOGIN_REQUIRED);
-
- my $type = $params->{type};
- $type || ThrowCodeError('param_required',
- { function => 'MyDashboard.run_flag_query',
- param => 'type' });
-
- my $results = query_flags($type);
-
- # Set the data type properly for webservice clients
- # for non-string values.
- foreach my $flag (@$results) {
- $flag->{id} = $self->type('int', $flag->{id});
- $flag->{attach_id} = $self->type('int', $flag->{attach_id});
- $flag->{bug_id} = $self->type('int', $flag->{bug_id});
- $flag->{is_patch} = $self->type('boolean', $flag->{is_patch});
- }
-
- return { result => { $type => $results }};
+ my ($self, $params) = @_;
+ my $user = Bugzilla->login(LOGIN_REQUIRED);
+
+ my $type = $params->{type};
+ $type
+ || ThrowCodeError('param_required',
+ {function => 'MyDashboard.run_flag_query', param => 'type'});
+
+ my $results = query_flags($type);
+
+ # Set the data type properly for webservice clients
+ # for non-string values.
+ foreach my $flag (@$results) {
+ $flag->{id} = $self->type('int', $flag->{id});
+ $flag->{attach_id} = $self->type('int', $flag->{attach_id});
+ $flag->{bug_id} = $self->type('int', $flag->{bug_id});
+ $flag->{is_patch} = $self->type('boolean', $flag->{is_patch});
+ }
+
+ return {result => {$type => $results}};
}
sub bug_interest_unmark {
- my ($self, $params) = @_;
- my $user = Bugzilla->login(LOGIN_REQUIRED);
+ my ($self, $params) = @_;
+ my $user = Bugzilla->login(LOGIN_REQUIRED);
- ThrowCodeError('param_required', { function => 'MyDashboard.bug_interest_unmark', param => 'bug_ids' })
- unless $params->{bug_ids};
+ ThrowCodeError('param_required',
+ {function => 'MyDashboard.bug_interest_unmark', param => 'bug_ids'})
+ unless $params->{bug_ids};
- my @bug_ids = ref($params->{bug_ids}) ? @{$params->{bug_ids}} : ( $params->{bug_ids} );
+ my @bug_ids
+ = ref($params->{bug_ids}) ? @{$params->{bug_ids}} : ($params->{bug_ids});
- Bugzilla->dbh->bz_start_transaction();
- foreach my $bug_id (@bug_ids) {
- Bugzilla::Extension::MyDashboard::BugInterest->unmark($user->id, $bug_id);
- }
- Bugzilla->dbh->bz_commit_transaction();
+ Bugzilla->dbh->bz_start_transaction();
+ foreach my $bug_id (@bug_ids) {
+ Bugzilla::Extension::MyDashboard::BugInterest->unmark($user->id, $bug_id);
+ }
+ Bugzilla->dbh->bz_commit_transaction();
}
sub rest_resources {
- return [
- qr{^/bug_interest_unmark$}, {
- PUT => {
- method => 'bug_interest_unmark'
- }
- }
- ];
+ return [qr{^/bug_interest_unmark$}, {PUT => {method => 'bug_interest_unmark'}}];
}
1;