Bug 352403: Create an object for saved searches, and have Bugzilla::User use it
Patch By Max Kanat-Alexander <mkanat@bugzilla.org> r=LpSolit, a=myk git-svn-id: svn://10.0.0.236/trunk@214674 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
parent
476c82f11a
commit
e3263b4efe
@ -81,6 +81,20 @@ sub _rederive_regexp {
|
||||
RederiveRegexp($self->user_regexp, $self->id);
|
||||
}
|
||||
|
||||
sub members_non_inherited {
|
||||
my ($self) = @_;
|
||||
return $self->{members_non_inherited}
|
||||
if exists $self->{members_non_inherited};
|
||||
|
||||
my $member_ids = Bugzilla->dbh->selectcol_arrayref(
|
||||
'SELECT DISTINCT user_id FROM user_group_map
|
||||
WHERE isbless = 0 AND group_id = ?',
|
||||
undef, $self->id) || [];
|
||||
require Bugzilla::User;
|
||||
$self->{members_non_inherited} = Bugzilla::User->new_from_list($member_ids);
|
||||
return $self->{members_non_inherited};
|
||||
}
|
||||
|
||||
################################
|
||||
##### Module Subroutines ###
|
||||
################################
|
||||
@ -246,3 +260,16 @@ be a member of this group.
|
||||
and undef otherwise.
|
||||
|
||||
=back
|
||||
|
||||
=head1 METHODS
|
||||
|
||||
=over
|
||||
|
||||
=item C<members_non_inherited>
|
||||
|
||||
Returns an arrayref of L<Bugzilla::User> objects representing people who are
|
||||
"directly" in this group, meaning that they're in it because they match
|
||||
the group regular expression, or they have been actually added to the
|
||||
group manually.
|
||||
|
||||
=back
|
||||
|
||||
186
mozilla/webtools/bugzilla/Bugzilla/Search/Saved.pm
Normal file
186
mozilla/webtools/bugzilla/Bugzilla/Search/Saved.pm
Normal file
@ -0,0 +1,186 @@
|
||||
# -*- Mode: perl; indent-tabs-mode: nil -*-
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public
|
||||
# License Version 1.1 (the "License"); you may not use this file
|
||||
# except in compliance with the License. You may obtain a copy of
|
||||
# the License at http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is the Bugzilla Bug Tracking System.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Everything Solved.
|
||||
# Portions created by Everything Solved are Copyright (C) 2006
|
||||
# Everything Solved. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s): Max Kanat-Alexander <mkanat@bugzilla.org>
|
||||
|
||||
use strict;
|
||||
|
||||
package Bugzilla::Search::Saved;
|
||||
|
||||
use base qw(Bugzilla::Object);
|
||||
|
||||
use Bugzilla::CGI;
|
||||
use Bugzilla::Constants;
|
||||
use Bugzilla::Group;
|
||||
use Bugzilla::Search qw(IsValidQueryType);
|
||||
use Bugzilla::User;
|
||||
|
||||
#############
|
||||
# Constants #
|
||||
#############
|
||||
|
||||
use constant DB_TABLE => 'namedqueries';
|
||||
|
||||
use constant DB_COLUMNS => qw(
|
||||
id
|
||||
userid
|
||||
name
|
||||
query
|
||||
query_type
|
||||
);
|
||||
|
||||
#####################
|
||||
# Complex Accessors #
|
||||
#####################
|
||||
|
||||
sub edit_link {
|
||||
my ($self) = @_;
|
||||
return $self->{edit_link} if defined $self->{edit_link};
|
||||
my $cgi = new Bugzilla::CGI($self->url);
|
||||
if (!$cgi->param('query_type')
|
||||
|| !IsValidQueryType($cgi->param('query_type')))
|
||||
{
|
||||
$cgi->param('query_type', 'advanced');
|
||||
}
|
||||
$self->{edit_link} = $cgi->canonicalise_query;
|
||||
return $self->{edit_link};
|
||||
}
|
||||
|
||||
sub used_in_whine {
|
||||
my ($self) = @_;
|
||||
return $self->{used_in_whine} if exists $self->{used_in_whine};
|
||||
($self->{used_in_whine}) = Bugzilla->dbh->selectrow_array(
|
||||
'SELECT 1 FROM whine_events INNER JOIN whine_queries
|
||||
ON whine_events.id = whine_queries.eventid
|
||||
WHERE whine_events.owner_userid = ? AND query_name = ?', undef,
|
||||
$self->{userid}, $self->name) || 0;
|
||||
return $self->{used_in_whine};
|
||||
}
|
||||
|
||||
sub link_in_footer {
|
||||
my ($self, $user) = @_;
|
||||
# We only cache link_in_footer for the current Bugzilla->user.
|
||||
return $self->{link_in_footer} if exists $self->{link_in_footer} && !$user;
|
||||
my $user_id = $user ? $user->id : Bugzilla->user->id;
|
||||
my $link_in_footer = Bugzilla->dbh->selectrow_array(
|
||||
'SELECT 1 FROM namedqueries_link_in_footer
|
||||
WHERE namedquery_id = ? AND user_id = ?',
|
||||
undef, $self->id, $user_id) || 0;
|
||||
$self->{link_in_footer} = $link_in_footer if !$user;
|
||||
return $link_in_footer;
|
||||
}
|
||||
|
||||
sub shared_with_group {
|
||||
my ($self) = @_;
|
||||
return $self->{shared_with_group} if exists $self->{shared_with_group};
|
||||
# Bugzilla only currently supports sharing with one group, even
|
||||
# though the database backend allows for an infinite number.
|
||||
my ($group_id) = Bugzilla->dbh->selectrow_array(
|
||||
'SELECT group_id FROM namedquery_group_map WHERE namedquery_id = ?',
|
||||
undef, $self->id);
|
||||
$self->{shared_with_group} = $group_id ? new Bugzilla::Group($group_id)
|
||||
: undef;
|
||||
return $self->{shared_with_group};
|
||||
}
|
||||
|
||||
####################
|
||||
# Simple Accessors #
|
||||
####################
|
||||
|
||||
sub bug_ids_only { return ($_[0]->{'query_type'} == LIST_OF_BUGS) ? 1 : 0; }
|
||||
sub url { return $_[0]->{'query'}; }
|
||||
|
||||
sub user {
|
||||
my ($self) = @_;
|
||||
return $self->{user} if defined $self->{user};
|
||||
$self->{user} = new Bugzilla::User($self->{userid});
|
||||
return $self->{user};
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Bugzilla::Search::Saved - A saved search
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
use Bugzilla::Search::Saved;
|
||||
|
||||
my $query = new Bugzilla::Search::Saved($query_id);
|
||||
|
||||
my $edit_link = $query->edit_link;
|
||||
my $search_url = $query->url;
|
||||
my $owner = $query->user;
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This module exists to represent a L<Bugzilla::Search> that has been
|
||||
saved to the database.
|
||||
|
||||
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 METHODS
|
||||
|
||||
=head2 Constructors and Database Manipulation
|
||||
|
||||
=over
|
||||
|
||||
=item C<new>
|
||||
|
||||
Does not accept a bare C<name> argument. Instead, accepts only an id.
|
||||
|
||||
See also: L<Bugzilla::Object/new>.
|
||||
|
||||
=back
|
||||
|
||||
|
||||
=head2 Accessors
|
||||
|
||||
These return data about the object, without modifying the object.
|
||||
|
||||
=over
|
||||
|
||||
=item C<edit_link>
|
||||
|
||||
A url with which you can edit the search.
|
||||
|
||||
=item C<url>
|
||||
|
||||
The CGI parameters for the search, as a string.
|
||||
|
||||
=item C<link_in_footer>
|
||||
|
||||
Whether or not this search should be displayed in the footer for the
|
||||
I<current user> (not the owner of the search, but the person actually
|
||||
using Bugzilla right now).
|
||||
|
||||
=item C<bug_ids_only>
|
||||
|
||||
True if the search contains only a list of Bug IDs.
|
||||
|
||||
=item C<shared_with_group>
|
||||
|
||||
The L<Bugzilla::Group> that this search is shared with. C<undef> if
|
||||
this search isn't shared.
|
||||
|
||||
=back
|
||||
@ -272,58 +272,63 @@ sub nick {
|
||||
|
||||
sub queries {
|
||||
my $self = shift;
|
||||
|
||||
return $self->{queries} if defined $self->{queries};
|
||||
return [] unless $self->id;
|
||||
|
||||
my $dbh = Bugzilla->dbh;
|
||||
my $used_in_whine_ref = $dbh->selectall_hashref('
|
||||
SELECT DISTINCT query_name
|
||||
FROM whine_events we
|
||||
INNER JOIN whine_queries wq
|
||||
ON we.id = wq.eventid
|
||||
WHERE we.owner_userid = ?',
|
||||
'query_name', undef, $self->id);
|
||||
|
||||
# If the user is in any group, there may be shared queries to be included.
|
||||
my $or_nqgm_group_id_in_usergroups = '';
|
||||
if ($self->groups_as_string) {
|
||||
$or_nqgm_group_id_in_usergroups =
|
||||
'OR MAX(nqgm.group_id) IN (' . $self->groups_as_string . ') ';
|
||||
}
|
||||
|
||||
my $queries_ref = $dbh->selectall_arrayref('
|
||||
SELECT nq.id, MAX(userid) AS userid, name, query, query_type,
|
||||
MAX(nqgm.group_id) AS shared_with_group,
|
||||
COUNT(nql.namedquery_id) AS link_in_footer
|
||||
FROM namedqueries AS nq
|
||||
LEFT JOIN namedquery_group_map nqgm
|
||||
ON nqgm.namedquery_id = nq.id
|
||||
LEFT JOIN namedqueries_link_in_footer AS nql
|
||||
ON nql.namedquery_id = nq.id
|
||||
AND nql.user_id = ? ' .
|
||||
$dbh->sql_group_by('nq.id', 'name, query, query_type') .
|
||||
' HAVING MAX(nq.userid) = ? ' .
|
||||
$or_nqgm_group_id_in_usergroups .
|
||||
' ORDER BY UPPER(name)',
|
||||
{'Slice'=>{}}, $self->id, $self->id);
|
||||
|
||||
foreach my $queries_hash (@$queries_ref) {
|
||||
# For each query, determine whether it's being used in a whine.
|
||||
if (exists($$used_in_whine_ref{$queries_hash->{'name'}})) {
|
||||
$queries_hash->{'usedinwhine'} = 1;
|
||||
}
|
||||
|
||||
# For shared queries, provide the sharer's user object.
|
||||
if ($queries_hash->{'userid'} != $self->id) {
|
||||
$queries_hash->{'user'} = new Bugzilla::User($queries_hash->{'userid'});
|
||||
}
|
||||
}
|
||||
$self->{queries} = $queries_ref;
|
||||
|
||||
my $query_ids = $dbh->selectcol_arrayref(
|
||||
'SELECT id FROM namedqueries WHERE userid = ?', undef, $self->id);
|
||||
require Bugzilla::Search::Saved;
|
||||
$self->{queries} = Bugzilla::Search::Saved->new_from_list($query_ids);
|
||||
return $self->{queries};
|
||||
}
|
||||
|
||||
sub queries_subscribed {
|
||||
my $self = shift;
|
||||
return $self->{queries_subscribed} if defined $self->{queries_subscribed};
|
||||
return [] unless $self->id;
|
||||
|
||||
# Exclude the user's own queries.
|
||||
my @my_query_ids = map($_->id, @{$self->queries});
|
||||
my $query_id_string = join(',', @my_query_ids) || '-1';
|
||||
|
||||
# Only show subscriptions that we can still actually see. If a
|
||||
# user changes the shared group of a query, our subscription
|
||||
# will remain but we won't have access to the query anymore.
|
||||
my $subscribed_query_ids = Bugzilla->dbh->selectcol_arrayref(
|
||||
"SELECT lif.namedquery_id
|
||||
FROM namedqueries_link_in_footer lif
|
||||
INNER JOIN namedquery_group_map ngm
|
||||
ON ngm.namedquery_id = lif.namedquery_id
|
||||
WHERE lif.user_id = ?
|
||||
AND lif.namedquery_id NOT IN ($query_id_string)
|
||||
AND ngm.group_id IN (" . $self->groups_as_string . ")",
|
||||
undef, $self->id);
|
||||
require Bugzilla::Search::Saved;
|
||||
$self->{queries_subscribed} =
|
||||
Bugzilla::Search::Saved->new_from_list($subscribed_query_ids);
|
||||
return $self->{queries_subscribed};
|
||||
}
|
||||
|
||||
sub queries_available {
|
||||
my $self = shift;
|
||||
return $self->{queries_available} if defined $self->{queries_available};
|
||||
return [] unless $self->id;
|
||||
|
||||
# Exclude the user's own queries.
|
||||
my @my_query_ids = map($_->id, @{$self->queries});
|
||||
my $query_id_string = join(',', @my_query_ids) || '-1';
|
||||
|
||||
my $avail_query_ids = Bugzilla->dbh->selectcol_arrayref(
|
||||
'SELECT namedquery_id FROM namedquery_group_map
|
||||
WHERE group_id IN (' . $self->groups_as_string . ")
|
||||
AND namedquery_id NOT IN ($query_id_string)");
|
||||
require Bugzilla::Search::Saved;
|
||||
$self->{queries_available} =
|
||||
Bugzilla::Search::Saved->new_from_list($avail_query_ids);
|
||||
return $self->{queries_available};
|
||||
}
|
||||
|
||||
sub settings {
|
||||
my ($self) = @_;
|
||||
|
||||
@ -345,6 +350,8 @@ sub flush_queries_cache {
|
||||
my $self = shift;
|
||||
|
||||
delete $self->{queries};
|
||||
delete $self->{queries_subscribed};
|
||||
delete $self->{queries_available};
|
||||
}
|
||||
|
||||
sub groups {
|
||||
@ -1663,6 +1670,42 @@ confirmation screen.
|
||||
|
||||
=head1 METHODS
|
||||
|
||||
=head2 Saved and Shared Queries
|
||||
|
||||
=over
|
||||
|
||||
=item C<queries>
|
||||
|
||||
Returns an arrayref of the user's own saved queries, sorted by name. The
|
||||
array contains L<Bugzilla::Search::Saved> objects.
|
||||
|
||||
=item C<queries_subscribed>
|
||||
|
||||
Returns an arrayref of shared queries that the user has subscribed to.
|
||||
That is, these are shared queries that the user sees in their footer.
|
||||
This array contains L<Bugzilla::Search::Saved> objects.
|
||||
|
||||
=item C<queries_available>
|
||||
|
||||
Returns an arrayref of all queries to which the user could possibly
|
||||
subscribe. This includes the contents of L</queries_subscribed>.
|
||||
An array of L<Bugzilla::Search::Saved> objects.
|
||||
|
||||
=item C<flush_queries_cache>
|
||||
|
||||
Some code modifies the set of stored queries. Because C<Bugzilla::User> does
|
||||
not handle these modifications, but does cache the result of calling C<queries>
|
||||
internally, such code must call this method to flush the cached result.
|
||||
|
||||
=item C<queryshare_groups>
|
||||
|
||||
An arrayref of group ids. The user can share their own queries with these
|
||||
groups.
|
||||
|
||||
=back
|
||||
|
||||
=head2 Other Methods
|
||||
|
||||
=over
|
||||
|
||||
=item C<id>
|
||||
@ -1711,35 +1754,6 @@ returned.
|
||||
Sets the L<Bugzilla::Auth> object to be returned by C<authorizer()>.
|
||||
Should only be called by C<Bugzilla::Auth::login>, for the most part.
|
||||
|
||||
=item C<queries>
|
||||
|
||||
Returns an array of the user's named queries, sorted in a case-insensitive
|
||||
order by name. Each entry is a hash with five keys:
|
||||
|
||||
=over
|
||||
|
||||
=item *
|
||||
|
||||
id - The ID of the query
|
||||
|
||||
=item *
|
||||
|
||||
userid - The query owner's user ID
|
||||
|
||||
=item *
|
||||
|
||||
name - The name of the query
|
||||
|
||||
=item *
|
||||
|
||||
query - The text for the query
|
||||
|
||||
=item *
|
||||
|
||||
link_in_footer - Whether or not the query should be displayed in the footer.
|
||||
|
||||
=back
|
||||
|
||||
=item C<disabledtext>
|
||||
|
||||
Returns the disable text of the user, if any.
|
||||
@ -1758,12 +1772,6 @@ value - the value of this setting for this user. Will be the same
|
||||
is_default - a boolean to indicate whether the user has chosen to make
|
||||
a preference for themself or use the site default.
|
||||
|
||||
=item C<flush_queries_cache>
|
||||
|
||||
Some code modifies the set of stored queries. Because C<Bugzilla::User> does
|
||||
not handle these modifications, but does cache the result of calling C<queries>
|
||||
internally, such code must call this method to flush the cached result.
|
||||
|
||||
=item C<groups>
|
||||
|
||||
Returns a hashref of group names for groups the user is a member of. The keys
|
||||
|
||||
@ -20,8 +20,6 @@
|
||||
#%]
|
||||
|
||||
[%# INTERFACE:
|
||||
# queries: list of the named queries visible to the user, both own and shared
|
||||
# by others. Cleaned-up result of Bugzilla::User::queries.
|
||||
# queryshare_groups: list of groups the user may share queries with
|
||||
# (id, name).
|
||||
#%]
|
||||
@ -81,18 +79,18 @@
|
||||
—
|
||||
</td>
|
||||
</tr>
|
||||
[% FOREACH q = queries %]
|
||||
[% NEXT UNLESS q.userid == user.id %]
|
||||
[% FOREACH q = user.queries %]
|
||||
<tr>
|
||||
<td>[% q.name FILTER html %]</td>
|
||||
<td>
|
||||
<a href="buglist.cgi?cmdtype=runnamed&namedcmd=[% q.name FILTER url_quote %]">Run</a>
|
||||
</td>
|
||||
<td>
|
||||
<a href="query.cgi?[% q.query FILTER html %]&known_name=[% q.name FILTER url_quote %]">Edit</a>
|
||||
<a href="query.cgi?[% q.edit_link FILTER html %]&known_name=
|
||||
[% q.name FILTER url_quote %]">Edit</a>
|
||||
</td>
|
||||
<td>
|
||||
[% IF q.usedinwhine %]
|
||||
[% IF q.used_in_whine %]
|
||||
Remove from <a href="editwhines.cgi">whining</a> first
|
||||
[% ELSE %]
|
||||
<a href="buglist.cgi?cmdtype=dorem&remaction=forget&namedcmd=
|
||||
@ -112,7 +110,9 @@
|
||||
<option value="">Don't share</option>
|
||||
[% FOREACH group = queryshare_groups %]
|
||||
<option value="[% group.id %]"
|
||||
[% ' selected="selected"' IF q.shared_with_group == group.id %]>[% group.name FILTER html %]</option>
|
||||
[% ' selected="selected"'
|
||||
IF q.shared_with_group.id == group.id %]
|
||||
>[% group.name FILTER html %]</option>
|
||||
[% END %]
|
||||
</select>
|
||||
[% ELSE %]
|
||||
@ -144,8 +144,7 @@
|
||||
</th>
|
||||
</tr>
|
||||
[% found_shared_query = 0 %]
|
||||
[% FOREACH q = queries %]
|
||||
[% NEXT IF q.userid == user.id %]
|
||||
[% FOREACH q = user.queries_available %]
|
||||
[% found_shared_query = 1 %]
|
||||
<tr>
|
||||
<td>[% q.name FILTER html %]</td>
|
||||
@ -153,7 +152,7 @@
|
||||
<td>
|
||||
<a href="buglist.cgi?cmdtype=dorem&remaction=run&namedcmd=
|
||||
[% q.name FILTER url_quote %]&sharer_id=
|
||||
[% q.userid FILTER url_quote %]">Run</a>
|
||||
[% q.user.id FILTER url_quote %]">Run</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<input type="checkbox"
|
||||
|
||||
@ -54,7 +54,7 @@
|
||||
[%# Get existing lists of bugs for this user %]
|
||||
[% lists_of_bugs = [] %]
|
||||
[% FOREACH q = user.queries %]
|
||||
[% NEXT UNLESS q.query_type == constants.LIST_OF_BUGS %]
|
||||
[% NEXT UNLESS q.bug_ids_only %]
|
||||
[% lists_of_bugs.push(q.name) %]
|
||||
[% END %]
|
||||
|
||||
|
||||
@ -97,6 +97,14 @@
|
||||
href="buglist.cgi?cmdtype=runnamed&namedcmd=[% q.name FILTER url_quote %]">
|
||||
[% END %]
|
||||
|
||||
[% FOREACH q = user.queries_subscribed %]
|
||||
<link rel="Saved Search"
|
||||
title="[% q.name FILTER html %] ([% q.user.login FILTER html %])"
|
||||
href="buglist.cgi?cmdtype=dorem&remaction=run&namedcmd=
|
||||
[% q.name FILTER url_quote %]&sharer_id=
|
||||
[% q.user.id FILTER url_quote %]">
|
||||
[% END %]
|
||||
|
||||
[%# *** Bugzilla Administration Tools *** %]
|
||||
[% IF user.login %]
|
||||
[% '<link rel="Administration" title="Parameters"
|
||||
|
||||
@ -86,10 +86,12 @@
|
||||
|
||||
[%# Saved searches %]
|
||||
|
||||
[% IF user.showmybugslink OR user.queries.size %]
|
||||
[% IF user.showmybugslink OR user.queries.size
|
||||
OR user.queries_subscribed.size
|
||||
%]
|
||||
<li id="links-saved">
|
||||
<div class="label">
|
||||
Saved Searches:
|
||||
Saved Searches:
|
||||
</div>
|
||||
<ul class="links">
|
||||
[% IF user.showmybugslink %]
|
||||
@ -99,7 +101,6 @@
|
||||
[% END %]
|
||||
|
||||
[% FOREACH q = user.queries %]
|
||||
[% NEXT IF q.userid != user.id %]
|
||||
[% IF q.link_in_footer %]
|
||||
<li>[% '<span class="separator">| </span>' IF print_pipe %]
|
||||
<a href="buglist.cgi?cmdtype=runnamed&namedcmd=[% q.name FILTER url_quote %]">[% q.name FILTER html %]</a></li>
|
||||
@ -108,22 +109,20 @@
|
||||
[% END %]
|
||||
[% new_line = print_pipe %]
|
||||
[% print_pipe = 0 %]
|
||||
[% FOREACH q = user.queries %]
|
||||
[% NEXT IF q.userid == user.id %]
|
||||
[% IF q.link_in_footer %]
|
||||
[% IF new_line %]
|
||||
<br>
|
||||
[% new_line = 0 %]
|
||||
[% END %]
|
||||
<li>
|
||||
[% FOREACH q = user.queries_subscribed %]
|
||||
[% IF new_line %]
|
||||
<br>
|
||||
[% new_line = 0 %]
|
||||
[% END %]
|
||||
<li>
|
||||
[% '<span class="separator">| </span>' IF print_pipe %]
|
||||
<a href="buglist.cgi?cmdtype=dorem&remaction=run&namedcmd=
|
||||
[% q.name FILTER url_quote %]&sharer_id=
|
||||
[% q.userid FILTER url_quote %]"
|
||||
[% q.user.id FILTER url_quote %]"
|
||||
class="shared"
|
||||
title="Shared by [% q.user.identity FILTER html %]">[% q.name FILTER html FILTER no_break %]</a></li>
|
||||
[% print_pipe = 1 %]
|
||||
[% END %]
|
||||
title="Shared by [% q.user.identity FILTER html %]"
|
||||
>[% q.name FILTER html FILTER no_break %]</a></li>
|
||||
[% print_pipe = 1 %]
|
||||
[% END %]
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
@ -1537,7 +1537,7 @@
|
||||
|
||||
[% FOREACH q = Bugzilla.user.queries %]
|
||||
[% IF q.name == namedcmd %]
|
||||
or <a href="query.cgi?[% q.query FILTER html %]">edit</a>
|
||||
or <a href="query.cgi?[% q.url FILTER html %]">edit</a>
|
||||
[% END %]
|
||||
[% END %]
|
||||
|
||||
|
||||
@ -378,30 +378,9 @@ sub DoPermissions {
|
||||
|
||||
|
||||
sub DoSavedSearches {
|
||||
# 2004-12-13 - colin.ogilvie@gmail.com, bug 274397
|
||||
# Need to work around the possibly missing query_format=advanced
|
||||
my $dbh = Bugzilla->dbh;
|
||||
my $user = Bugzilla->user;
|
||||
|
||||
my @queries = @{$user->queries};
|
||||
my @newqueries;
|
||||
foreach my $q (@queries) {
|
||||
if ($q->{'query'} =~ /query_format=([^&]*)/) {
|
||||
my $format = $1;
|
||||
if (!IsValidQueryType($format)) {
|
||||
if ($format eq "") {
|
||||
$q->{'query'} =~ s/query_format=/query_format=advanced/;
|
||||
}
|
||||
else {
|
||||
$q->{'query'} .= '&query_format=advanced';
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$q->{'query'} .= '&query_format=advanced';
|
||||
}
|
||||
push @newqueries, $q;
|
||||
}
|
||||
$vars->{'queries'} = \@newqueries;
|
||||
if ($user->queryshare_groups_as_string) {
|
||||
$vars->{'queryshare_groups'} =
|
||||
Bugzilla::Group->new_from_list($user->queryshare_groups);
|
||||
@ -416,20 +395,12 @@ sub SaveSavedSearches {
|
||||
# We'll need this in a loop, so do the call once.
|
||||
my $user_id = $user->id;
|
||||
|
||||
my @queries = @{$user->queries};
|
||||
my $sth_check_nl = $dbh->prepare('SELECT COUNT(*)
|
||||
FROM namedqueries_link_in_footer
|
||||
WHERE namedquery_id = ?
|
||||
AND user_id = ?');
|
||||
my $sth_insert_nl = $dbh->prepare('INSERT INTO namedqueries_link_in_footer
|
||||
(namedquery_id, user_id)
|
||||
VALUES (?, ?)');
|
||||
my $sth_delete_nl = $dbh->prepare('DELETE FROM namedqueries_link_in_footer
|
||||
WHERE namedquery_id = ?
|
||||
AND user_id = ?');
|
||||
my $sth_check_ngm = $dbh->prepare('SELECT COUNT(*)
|
||||
FROM namedquery_group_map
|
||||
WHERE namedquery_id = ?');
|
||||
my $sth_insert_ngm = $dbh->prepare('INSERT INTO namedquery_group_map
|
||||
(namedquery_id, group_id)
|
||||
VALUES (?, ?)');
|
||||
@ -438,83 +409,64 @@ sub SaveSavedSearches {
|
||||
WHERE namedquery_id = ?');
|
||||
my $sth_delete_ngm = $dbh->prepare('DELETE FROM namedquery_group_map
|
||||
WHERE namedquery_id = ?');
|
||||
my $sth_direct_group_members =
|
||||
$dbh->prepare('SELECT user_id
|
||||
FROM user_group_map
|
||||
WHERE group_id = ?
|
||||
AND isbless = ' . GROUP_MEMBERSHIP . '
|
||||
AND grant_type = ' . GRANT_DIRECT);
|
||||
foreach my $q (@queries) {
|
||||
# Update namedqueries_link_in_footer.
|
||||
$sth_check_nl->execute($q->{'id'}, $user_id);
|
||||
my ($link_in_footer_entries) = $sth_check_nl->fetchrow_array();
|
||||
if (defined($cgi->param("link_in_footer_$q->{'id'}"))) {
|
||||
if ($link_in_footer_entries == 0) {
|
||||
$sth_insert_nl->execute($q->{'id'}, $user_id);
|
||||
|
||||
# Update namedqueries_link_in_footer for this user.
|
||||
foreach my $q (@{$user->queries}, @{$user->queries_available}) {
|
||||
if (defined $cgi->param("link_in_footer_" . $q->id)) {
|
||||
$sth_insert_nl->execute($q->id, $user_id) if !$q->link_in_footer;
|
||||
}
|
||||
else {
|
||||
$sth_delete_nl->execute($q->id, $user_id) if $q->link_in_footer;
|
||||
}
|
||||
}
|
||||
|
||||
# For user's own queries, update namedquery_group_map.
|
||||
foreach my $q (@{$user->queries}) {
|
||||
my $group_id;
|
||||
|
||||
if ($user->in_group(Bugzilla->params->{'querysharegroup'})) {
|
||||
$group_id = $cgi->param("share_" . $q->id) || '';
|
||||
}
|
||||
|
||||
if ($group_id) {
|
||||
# Don't allow the user to share queries with groups he's not
|
||||
# allowed to.
|
||||
next unless grep($_ eq $group_id, @{$user->queryshare_groups});
|
||||
|
||||
# $group_id is now definitely a valid ID of a group the
|
||||
# user can share queries with, so we can trick_taint.
|
||||
detaint_natural($group_id);
|
||||
if ($q->shared_with_group) {
|
||||
$sth_update_ngm->execute($group_id, $q->id);
|
||||
}
|
||||
else {
|
||||
$sth_insert_ngm->execute($q->id, $group_id);
|
||||
}
|
||||
|
||||
# If we're sharing our query with a group we can bless, we
|
||||
# subscribe direct group members to our search automatically.
|
||||
# Otherwise, the group members need to opt in. This behaviour
|
||||
# is deemed most likely to fit users' needs.
|
||||
if ($user->can_bless($group_id)) {
|
||||
my $group = new Bugzilla::Group($group_id);
|
||||
my $members = $group->members_non_inherited;
|
||||
foreach my $member (@$members) {
|
||||
next if $member->id == $user->id;
|
||||
$sth_insert_nl->execute($q->id, $member->id)
|
||||
if !$q->link_in_footer($member);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ($link_in_footer_entries > 0) {
|
||||
$sth_delete_nl->execute($q->{'id'}, $user_id);
|
||||
# They have unshared that query.
|
||||
if ($q->shared_with_group) {
|
||||
$sth_delete_ngm->execute($q->id);
|
||||
}
|
||||
}
|
||||
|
||||
# For user's own queries, update namedquery_group_map.
|
||||
if ($q->{'userid'} == $user_id) {
|
||||
my ($group_id, $group_map_entries);
|
||||
if ($user->in_group(Bugzilla->params->{'querysharegroup'})) {
|
||||
$sth_check_ngm->execute($q->{'id'});
|
||||
($group_map_entries) = $sth_check_ngm->fetchrow_array();
|
||||
$group_id = $cgi->param("share_$q->{'id'}") || '';
|
||||
}
|
||||
if ($group_id) {
|
||||
if (grep(/^\Q$group_id\E$/, @{$user->queryshare_groups()})) {
|
||||
# $group_id is now definitely a valid ID of a group the
|
||||
# user can see, so we can trick_taint.
|
||||
trick_taint($group_id);
|
||||
if ($group_map_entries == 0) {
|
||||
$sth_insert_ngm->execute($q->{'id'}, $group_id);
|
||||
}
|
||||
else {
|
||||
$sth_update_ngm->execute($group_id, $q->{'id'});
|
||||
}
|
||||
|
||||
# If we're sharing our query with a group we can bless,
|
||||
# we're subscribing direct group members to our search
|
||||
# automatically. Otherwise, the group members need to
|
||||
# opt in. This behaviour is deemed most likely to fit
|
||||
# users' needs.
|
||||
if ($user->can_bless($group_id)) {
|
||||
$sth_direct_group_members->execute($group_id);
|
||||
my $user_id;
|
||||
while ($user_id =
|
||||
$sth_direct_group_members->fetchrow_array()) {
|
||||
next if $user_id == $user->id;
|
||||
|
||||
$sth_check_nl->execute($q->{'id'}, $user_id);
|
||||
my ($already_shown_in_footer) =
|
||||
$sth_check_nl->fetchrow_array();
|
||||
if (! $already_shown_in_footer) {
|
||||
$sth_insert_nl->execute($q->{'id'}, $user_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
# In the unlikely case somebody removed visibility to the
|
||||
# group in the meantime, don't modify sharing.
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ($group_map_entries > 0) {
|
||||
$sth_delete_ngm->execute($q->{'id'});
|
||||
}
|
||||
|
||||
# Don't remove namedqueries_link_in_footer entries for users
|
||||
# subscribing to the shared query. The idea is that they will
|
||||
# probably want to be subscribers again should the sharing
|
||||
# user choose to share the query again.
|
||||
}
|
||||
# Don't remove namedqueries_link_in_footer entries for users
|
||||
# subscribing to the shared query. The idea is that they will
|
||||
# probably want to be subscribers again should the sharing
|
||||
# user choose to share the query again.
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user