blob: e774c7fe0593b762bf170144ef946d4906c95955 [file] [log] [blame]
# 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::Search::Recent;
use 5.10.1;
use strict;
use warnings;
use parent qw(Bugzilla::Object);
use Bugzilla::Constants;
use Bugzilla::Error;
use Bugzilla::Util;
#############
# Constants #
#############
use constant DB_TABLE => 'profile_search';
use constant LIST_ORDER => 'id DESC';
# Do not track buglists viewed by users.
use constant AUDIT_CREATES => 0;
use constant AUDIT_UPDATES => 0;
use constant AUDIT_REMOVES => 0;
use constant DB_COLUMNS => qw(
id
user_id
bug_list
list_order
);
use constant VALIDATORS => {
user_id => \&_check_user_id,
bug_list => \&_check_bug_list,
list_order => \&_check_list_order,
};
use constant UPDATE_COLUMNS => qw(bug_list list_order);
# There's no gain to caching these objects
use constant USE_MEMCACHED => 0;
###################
# DB Manipulation #
###################
sub create {
my $class = shift;
my $dbh = Bugzilla->dbh;
$dbh->bz_start_transaction();
my $search = $class->SUPER::create(@_);
my $user_id = $search->user_id;
# Enforce there only being SAVE_NUM_SEARCHES per user.
my @ids = @{ $dbh->selectcol_arrayref(
"SELECT id FROM profile_search WHERE user_id = ? ORDER BY id",
undef, $user_id) };
if (scalar(@ids) > SAVE_NUM_SEARCHES) {
splice(@ids, - SAVE_NUM_SEARCHES);
$dbh->do(
"DELETE FROM profile_search WHERE id IN (" . join(',', @ids) . ")");
}
$dbh->bz_commit_transaction();
return $search;
}
sub create_placeholder {
my $class = shift;
return $class->create({ user_id => Bugzilla->user->id,
bug_list => '' });
}
###############
# Constructor #
###############
sub check {
my $class = shift;
my $search = $class->SUPER::check(@_);
my $user = Bugzilla->user;
if ($search->user_id != $user->id) {
ThrowUserError('object_does_not_exist', { id => $search->id });
}
return $search;
}
sub check_quietly {
my $class = shift;
my $error_mode = Bugzilla->error_mode;
Bugzilla->error_mode(ERROR_MODE_DIE);
my $search = eval { $class->check(@_) };
Bugzilla->error_mode($error_mode);
return $search;
}
sub new_from_cookie {
my ($invocant, $bug_ids) = @_;
my $class = ref($invocant) || $invocant;
my $search = { id => 'cookie',
user_id => Bugzilla->user->id,
bug_list => join(',', @$bug_ids) };
bless $search, $class;
return $search;
}
####################
# Simple Accessors #
####################
sub bug_list { return [split(',', $_[0]->{'bug_list'})]; }
sub list_order { return $_[0]->{'list_order'}; }
sub user_id { return $_[0]->{'user_id'}; }
############
# Mutators #
############
sub set_bug_list { $_[0]->set('bug_list', $_[1]); }
sub set_list_order { $_[0]->set('list_order', $_[1]); }
##############
# Validators #
##############
sub _check_user_id {
my ($invocant, $id) = @_;
require Bugzilla::User;
return Bugzilla::User->check({ id => $id })->id;
}
sub _check_bug_list {
my ($invocant, $list) = @_;
my @bug_ids = ref($list) ? @$list : split(',', $list || '');
detaint_natural($_) foreach @bug_ids;
return join(',', @bug_ids);
}
sub _check_list_order { defined $_[1] ? trim($_[1]) : '' }
1;
__END__
=head1 NAME
Bugzilla::Search::Recent - A search recently run by a logged-in user.
=head1 SYNOPSIS
use Bugzilla::Search::Recent;
=head1 DESCRIPTION
This is an implementation of L<Bugzilla::Object>, and so has all the
same methods available as L<Bugzilla::Object>, in addition to what is
documented below.
=head1 B<Methods in need of POD>
=over
=item create
=item list_order
=item check_quietly
=item new_from_cookie
=item create_placeholder
=item bug_list
=item set_bug_list
=item user_id
=item set_list_order
=back