From 559f89582199e4ca531398a5cadd03632526d525 Mon Sep 17 00:00:00 2001 From: "mkanat%bugzilla.org" <> Date: Wed, 7 Jan 2009 21:22:08 +0000 Subject: Bug 450403: Add ability to view comments via the web service (Bug.comments) Patch By Max Kanat-Alexander r=dkl, a=mkanat --- Bugzilla/WebService/Bug.pm | 196 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 196 insertions(+) (limited to 'Bugzilla/WebService/Bug.pm') diff --git a/Bugzilla/WebService/Bug.pm b/Bugzilla/WebService/Bug.pm index aaaf753a3..10ea1f886 100755 --- a/Bugzilla/WebService/Bug.pm +++ b/Bugzilla/WebService/Bug.pm @@ -27,6 +27,7 @@ use Bugzilla::Constants; use Bugzilla::Error; use Bugzilla::Field; use Bugzilla::WebService::Constants; +use Bugzilla::WebService::Util qw(filter); use Bugzilla::Bug; use Bugzilla::BugMail; use Bugzilla::Util qw(trim); @@ -58,6 +59,84 @@ BEGIN { *get_bugs = \&get } # Methods # ########### +sub comments { + my ($self, $params) = @_; + if (!(defined $params->{bug_ids} || defined $params->{comment_ids})) { + ThrowCodeError('params_required', + { function => 'Bug.comments', + params => ['bug_ids', 'comment_ids'] }); + } + + my $bug_ids = $params->{bug_ids} || []; + my $comment_ids = $params->{comment_ids} || []; + + my $dbh = Bugzilla->dbh; + my $user = Bugzilla->user; + + my %bugs; + foreach my $bug_id (@$bug_ids) { + my $bug = Bugzilla::Bug->check($bug_id); + # We want the API to always return comments in the same order. + my $comments = Bugzilla::Bug::GetComments( + $bug->id, 'oldest_to_newest'); + my @result; + foreach my $comment (@$comments) { + next if $comment->{isprivate} && !$user->is_insider; + $comment->{bug_id} = $bug->id; + push(@result, $self->_translate_comment($comment, $params)); + } + $bugs{$bug->id}{'comments'} = \@result; + } + + my %comments; + if (scalar @$comment_ids) { + my @ids = map { trim($_) } @$comment_ids; + my @sql_ids = map { $dbh->quote($_) } @ids; + my $comment_data = $dbh->selectall_arrayref( + 'SELECT comment_id AS id, bug_id, who, bug_when AS time, + isprivate, thetext AS body, type, extra_data + FROM longdescs WHERE ' . $dbh->sql_in('comment_id', \@sql_ids), + {Slice=>{}}); + + # See if we were passed any invalid comment ids. + my %got_ids = map { $_->{id} => 1 } @$comment_data; + foreach my $comment_id (@ids) { + if (!$got_ids{$comment_id}) { + ThrowUserError('comment_id_invalid', { id => $comment_id }); + } + } + + # Now make sure that we can see all the associated bugs. + my %got_bug_ids = map { $_->{bug_id} => 1 } @$comment_data; + Bugzilla::Bug->check($_) foreach (keys %got_bug_ids); + + foreach my $comment (@$comment_data) { + if ($comment->{isprivate} && !$user->is_insider) { + ThrowUserError('comment_is_private', { id => $comment->{id} }); + } + $comment->{author} = new Bugzilla::User($comment->{who}); + $comment->{body} = Bugzilla::Bug::format_comment($comment); + $comments{$comment->{id}} = + $self->_translate_comment($comment, $params); + } + } + + return { bugs => \%bugs, comments => \%comments }; +} + +# Helper for Bug.comments +sub _translate_comment { + my ($self, $comment, $filters) = @_; + return filter $filters, { + id => $self->type('int', $comment->{id}), + bug_id => $self->type('int', $comment->{bug_id}), + author => $self->type('string', $comment->{author}->login), + time => $self->type('dateTime', $comment->{'time'}), + is_private => $self->type('boolean', $comment->{isprivate}), + text => $self->type('string', $comment->{body}), + }; +} + sub get { my ($self, $params) = @_; my $ids = $params->{ids}; @@ -326,6 +405,123 @@ You specified a field that doesn't exist or isn't a drop-down field. =over + +=item C + +B + +=over + +=item B + +This allows you to get data about comments, given a list of bugs +and/or comment ids. + +=item B + +B: At least one of C or C is required. + +In addition to the parameters below, this method also accepts the +standard L and +L arguments. + +=over + +=item C + +C An array that can contain both bug IDs and bug aliases. +All of the comments (that are visible to you) will be returned for the +specified bugs. + +=item C + +C An array of integer comment_ids. These comments will be +returned individually, separate from any other comments in their +respective bugs. + +=back + +=item B + +Two items are returned: + +=over + +=item C + +This is used for bugs specified in C. This is a hash, +where the keys are the numeric ids of the bugs, and the value is +a hash with a single key, C, which is an array of comments. +(The format of comments is described below.) + +Note that any individual bug will only be returned once, so if you +specify an id multiple times in C, it will still only be +returned once. + +=item C + +Each individual comment requested in C is returned here, +in a hash where the numeric comment id is the key, and the value +is the comment. (The format of comments is described below.) + +=back + +A "comment" as described above is a hash that contains the following +keys: + +=over + +=item id + +C The globally unique ID for the comment. + +=item bug_id + +C The ID of the bug that this comment is on. + +=item text + +C The actual text of the comment. + +=item author + +C The login name of the comment's author. + +=item time + +C The time (in Bugzilla's timezone) that the comment was added. + +=item is_private + +C True if this comment is private (only visible to a certain +group called the "insidergroup"), False otherwise. + +=back + +=item B + +This method can throw all the same errors as L. In addition, +it can also throw the following errors: + +=over + +=item 110 (Comment Is Private) + +You specified the id of a private comment in the C +argument, and you are not in the "insider group" that can see +private comments. + +=item 111 (Invalid Comment ID) + +You specified an id in the C argument that is invalid--either +you specified something that wasn't a number, or there is no comment with +that id. + +=back + +=back + + =item C B -- cgit v1.2.3-24-g4f1b