summaryrefslogtreecommitdiffstats
path: root/Bugzilla/User.pm
diff options
context:
space:
mode:
authorMax Kanat-Alexander <mkanat@bugzilla.org>2010-06-16 03:40:27 +0200
committerMax Kanat-Alexander <mkanat@bugzilla.org>2010-06-16 03:40:27 +0200
commitfbe9a7a9a22004e3cc23a61b84148da8a0c300e9 (patch)
tree0fec2fa81dcaac47c45b56c6b696b10a53a27270 /Bugzilla/User.pm
parent4291fb9fc4f9210d1ca54ca559d701b5cdca13b5 (diff)
downloadbugzilla-fbe9a7a9a22004e3cc23a61b84148da8a0c300e9.tar.gz
bugzilla-fbe9a7a9a22004e3cc23a61b84148da8a0c300e9.tar.xz
Bug 24896: Make the First/Last/Prev/Next navigation on bugs work with
multiple buglists at once r=glob, a=mkanat
Diffstat (limited to 'Bugzilla/User.pm')
-rw-r--r--Bugzilla/User.pm147
1 files changed, 147 insertions, 0 deletions
diff --git a/Bugzilla/User.pm b/Bugzilla/User.pm
index 936cf36e4..815b435fd 100644
--- a/Bugzilla/User.pm
+++ b/Bugzilla/User.pm
@@ -44,6 +44,7 @@ package Bugzilla::User;
use Bugzilla::Error;
use Bugzilla::Util;
use Bugzilla::Constants;
+use Bugzilla::Search::Recent;
use Bugzilla::User::Setting;
use Bugzilla::Product;
use Bugzilla::Classification;
@@ -51,8 +52,11 @@ use Bugzilla::Field;
use Bugzilla::Group;
use DateTime::TimeZone;
+use List::Util qw(max);
use Scalar::Util qw(blessed);
use Storable qw(dclone);
+use URI;
+use URI::QueryParam;
use base qw(Bugzilla::Object Exporter);
@Bugzilla::User::EXPORT = qw(is_available_username
@@ -361,6 +365,149 @@ sub queries_available {
return $self->{queries_available};
}
+##########################
+# Saved Recent Bug Lists #
+##########################
+
+sub recent_searches {
+ my $self = shift;
+ $self->{recent_searches} ||=
+ Bugzilla::Search::Recent->match({ user_id => $self->id });
+ return $self->{recent_searches};
+}
+
+sub recent_search_containing {
+ my ($self, $bug_id) = @_;
+ my $searches = $self->recent_searches;
+
+ foreach my $search (@$searches) {
+ return $search if grep($_ == $bug_id, @{ $search->bug_list });
+ }
+
+ return undef;
+}
+
+sub recent_search_for {
+ my ($self, $bug) = @_;
+ my $params = Bugzilla->input_params;
+ my $cgi = Bugzilla->cgi;
+
+ if ($self->id) {
+ # First see if there's a list_id parameter in the query string.
+ my $list_id = $params->{list_id};
+ if (!$list_id) {
+ # If not, check for "list_id" in the query string of the referer.
+ my $referer = $cgi->referer;
+ if ($referer) {
+ my $uri = URI->new($referer);
+ if ($uri->path =~ /buglist\.cgi$/) {
+ $list_id = $uri->query_param('list_id')
+ || $uri->query_param('regetlastlist');
+ }
+ }
+ }
+
+ if ($list_id) {
+ # If we got a bad list_id (either some other user's or an expired
+ # one) don't crash, just don't return that list.
+ my $search =
+ eval { Bugzilla::Search::Recent->check({ id => $list_id }) };
+ return $search if $search;
+ }
+
+ # If there's no list_id, see if the current bug's id is contained
+ # in any of the user's saved lists.
+ my $search = $self->recent_search_containing($bug->id);
+ return $search if $search;
+ }
+
+ # Finally (or always, if we're logged out), if there's a BUGLIST cookie
+ # and the selected bug is in the list, then return the cookie as a fake
+ # Search::Recent object.
+ if (my $list = $cgi->cookie('BUGLIST')) {
+ my @bug_ids = split(':', $list);
+ if (grep { $_ == $bug->id } @bug_ids) {
+ return { id => 'cookie', bug_list => \@bug_ids };
+ }
+ }
+
+ return undef;
+}
+
+sub save_last_search {
+ my ($self, $params) = @_;
+ my ($bug_ids, $order, $vars, $list_id) =
+ @$params{qw(bugs order vars list_id)};
+
+ my $cgi = Bugzilla->cgi;
+ if ($order) {
+ $cgi->send_cookie(-name => 'LASTORDER',
+ -value => $order,
+ -expires => 'Fri, 01-Jan-2038 00:00:00 GMT');
+ }
+
+ return if !@$bug_ids;
+
+ if ($self->id) {
+ on_main_db {
+ my $search;
+ if ($list_id) {
+ # Use eval so that people can still use old search links or
+ # links that don't belong to them.
+ $search = eval { Bugzilla::Search::Recent->check(
+ { id => $list_id }) };
+ }
+
+ if ($search) {
+ # We only update placeholders. (Placeholders are
+ # Saved::Search::Recent objects with empty bug lists.)
+ # Otherwise, we could just keep creating new searches
+ # for the same refreshed list over and over.
+ if (!@{ $search->bug_list }) {
+ $search->set_list_order($order);
+ $search->set_bug_list($bug_ids);
+ $search->update();
+ }
+ }
+ else {
+ # If we already have an existing search with a totally
+ # identical bug list, then don't create a new one. This
+ # prevents people from writing over their whole
+ # recent-search list by just refreshing a saved search
+ # (which doesn't have list_id in the header) over and over.
+ my $list_string = join(',', @$bug_ids);
+ my $existing_search = Bugzilla::Search::Recent->match({
+ user_id => $self->id, bug_list => $list_string });
+
+ if (!scalar(@$existing_search)) {
+ Bugzilla::Search::Recent->create({
+ user_id => $self->id,
+ bug_list => $bug_ids,
+ list_order => $order });
+ }
+ }
+ };
+ delete $self->{recent_searches};
+ }
+ # Logged-out users use a cookie to store a single last search. We don't
+ # override that cookie with the logged-in user's latest search, because
+ # if they did one search while logged out and another while logged in,
+ # they may still want to navigate through the search they made while
+ # logged out.
+ else {
+ my $bug_list = join(":", @$bug_ids);
+ if (length($bug_list) < 4000) {
+ $cgi->send_cookie(-name => 'BUGLIST',
+ -value => $bug_list,
+ -expires => 'Fri, 01-Jan-2038 00:00:00 GMT');
+ }
+ else {
+ $cgi->remove_cookie('BUGLIST');
+ $vars->{'toolong'} = 1;
+ }
+ }
+}
+
sub settings {
my ($self) = @_;