зеркало из https://github.com/mozilla/gecko-dev.git
Bug 286158: Remove GetSelectableProducts() from globals.pl and use Bugzilla::User::get_selectable_products() instead - Patch by Fr�d�ric Buclin <LpSolit@gmail.com> r=joel,kiko a=justdave
This commit is contained in:
Родитель
f8ad8c3f24
Коммит
426b5bd478
|
@ -121,11 +121,11 @@ sub get_components_by_product {
|
|||
SELECT id FROM components
|
||||
WHERE product_id = ?}, undef, $product_id);
|
||||
|
||||
my $components;
|
||||
my @components;
|
||||
foreach my $id (@$ids) {
|
||||
$components->{$id} = new Bugzilla::Component($id);
|
||||
push @components, new Bugzilla::Component($id);
|
||||
}
|
||||
return $components;
|
||||
return @components;
|
||||
}
|
||||
|
||||
1;
|
||||
|
@ -151,8 +151,7 @@ Bugzilla::Component - Bugzilla product component class.
|
|||
my $default_assignee = $component->default_assignee;
|
||||
my $default_qa_contact = $component->default_qa_contact;
|
||||
|
||||
my $hash_ref = Bugzilla::Component::get_components_by_product(1);
|
||||
my $component = $hash_ref->{1};
|
||||
my @components = Bugzilla::Component::get_components_by_product($id);
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
|
@ -184,13 +183,11 @@ Component.pm represents a Product Component object.
|
|||
|
||||
=item C<get_components_by_product($product_id)>
|
||||
|
||||
Description: Returns all Bugzilla components that belong to the
|
||||
supplied product.
|
||||
Description: Returns all components that belong to the supplied product.
|
||||
|
||||
Params: $product_id - Integer with a Bugzilla product id.
|
||||
|
||||
Returns: A hash with component id as key and Bugzilla::Component
|
||||
object as value.
|
||||
Returns: An array of Bugzilla::Component objects.
|
||||
|
||||
=back
|
||||
|
||||
|
|
|
@ -98,8 +98,9 @@ sub components {
|
|||
my $self = shift;
|
||||
|
||||
if (!defined $self->{components}) {
|
||||
$self->{components} =
|
||||
my @components =
|
||||
Bugzilla::Component::get_components_by_product($self->id);
|
||||
$self->{components} = \@components;
|
||||
}
|
||||
return $self->{components};
|
||||
}
|
||||
|
@ -247,11 +248,11 @@ Bugzilla::Product - Bugzilla product class.
|
|||
my $product = new Bugzilla::Product(1);
|
||||
my $product = new Bugzilla::Product('AcmeProduct');
|
||||
|
||||
my $components = $product->components();
|
||||
my @components = $product->components();
|
||||
my $classification = $product->classification();
|
||||
my $hash_ref = $product->group_controls();
|
||||
my @array_ref = $product->milestones();
|
||||
my @array_ref = $product->versions();
|
||||
my $groups_controls = $product->group_controls();
|
||||
my @milestones = $product->milestones();
|
||||
my @versions = $product->versions();
|
||||
my $bugcount = $product->bug_count();
|
||||
|
||||
my $id = $product->id;
|
||||
|
@ -290,12 +291,12 @@ Product.pm represents a product object.
|
|||
|
||||
=item C<components()>
|
||||
|
||||
Description: Returns a hash with all product components.
|
||||
Description: Returns an array of component objects belonging to
|
||||
the product.
|
||||
|
||||
Params: none.
|
||||
|
||||
Returns: A hash where component id is the hash key and
|
||||
Bugzilla::Component object is the hash value.
|
||||
Returns: An array of Bugzilla::Component object.
|
||||
|
||||
=item C<classification()>
|
||||
|
||||
|
|
|
@ -61,8 +61,6 @@ use constant USER_MATCH_SUCCESS => 1;
|
|||
|
||||
use constant MATCH_SKIP_CONFIRM => 1;
|
||||
|
||||
use constant GET_PRODUCTS_BY_ID => 1;
|
||||
|
||||
################################################################################
|
||||
# Functions
|
||||
################################################################################
|
||||
|
@ -420,13 +418,12 @@ sub can_see_bug {
|
|||
sub get_selectable_products {
|
||||
my ($self, $by_id) = @_;
|
||||
|
||||
if (defined $self->{SelectableProducts}) {
|
||||
my %list = @{$self->{SelectableProducts}};
|
||||
return \%list if $by_id;
|
||||
return values(%list);
|
||||
if (defined $self->{selectable_products}) {
|
||||
return $self->{selectable_products};
|
||||
}
|
||||
|
||||
my $query = "SELECT id, name " .
|
||||
my $dbh = Bugzilla->dbh;
|
||||
my $query = "SELECT id " .
|
||||
"FROM products " .
|
||||
"LEFT JOIN group_control_map " .
|
||||
"ON group_control_map.product_id = products.id ";
|
||||
|
@ -439,38 +436,31 @@ sub get_selectable_products {
|
|||
$query .= "AND group_id NOT IN(" .
|
||||
$self->groups_as_string . ") " .
|
||||
"WHERE group_id IS NULL ORDER BY name";
|
||||
my $dbh = Bugzilla->dbh;
|
||||
my $sth = $dbh->prepare($query);
|
||||
$sth->execute();
|
||||
my @products = ();
|
||||
while (my @row = $sth->fetchrow_array) {
|
||||
push(@products, @row);
|
||||
|
||||
my $prod_ids = $dbh->selectcol_arrayref($query);
|
||||
my @products;
|
||||
foreach my $prod_id (@$prod_ids) {
|
||||
push(@products, new Bugzilla::Product($prod_id));
|
||||
}
|
||||
$self->{SelectableProducts} = \@products;
|
||||
my %list = @products;
|
||||
return \%list if $by_id;
|
||||
return values(%list);
|
||||
$self->{selectable_products} = \@products;
|
||||
return $self->{selectable_products};
|
||||
}
|
||||
|
||||
sub get_selectable_classifications ($) {
|
||||
sub get_selectable_classifications {
|
||||
my ($self) = @_;
|
||||
|
||||
if (defined $self->{selectable_classifications}) {
|
||||
return $self->{selectable_classifications};
|
||||
}
|
||||
|
||||
my $products = $self->get_selectable_products(GET_PRODUCTS_BY_ID);
|
||||
|
||||
my $selectable_classifications;
|
||||
|
||||
foreach my $prod_id (keys %$products) {
|
||||
my $product = new Bugzilla::Product($prod_id);
|
||||
|
||||
$selectable_classifications->{$product->classification_id} =
|
||||
$product->classification;
|
||||
|
||||
my $products = $self->get_selectable_products;
|
||||
|
||||
my $class;
|
||||
foreach my $product (@$products) {
|
||||
$class->{$product->classification_id} ||= $product->classification;
|
||||
}
|
||||
$self->{selectable_classifications} =
|
||||
[values %$selectable_classifications];
|
||||
my @sorted_class = sort {lc($a->name) cmp lc($b->name)} (values %$class);
|
||||
$self->{selectable_classifications} = \@sorted_class;
|
||||
return $self->{selectable_classifications};
|
||||
}
|
||||
|
||||
|
@ -1450,22 +1440,23 @@ care of by the constructor. However, when updating the email address, the
|
|||
user may be placed into different groups, based on a new email regexp. This
|
||||
method should be called in such a case to force reresolution of these groups.
|
||||
|
||||
=item C<get_selectable_products(by_id)>
|
||||
=item C<get_selectable_products>
|
||||
|
||||
Returns an alphabetical list of product names from which
|
||||
the user can select bugs. If the $by_id parameter is true, it returns
|
||||
a hash where the keys are the product ids and the values are the
|
||||
product names.
|
||||
Description: Returns all products the user is allowed to access.
|
||||
|
||||
Params: none
|
||||
|
||||
Returns: An array of product objects, sorted by the product name.
|
||||
|
||||
=item C<get_selectable_classifications>
|
||||
|
||||
Description: Returns the classifications that a user, according his
|
||||
groups ownership, can select to entering, serch, view or
|
||||
edit a bug.
|
||||
Description: Returns all classifications containing at least one product
|
||||
the user is allowed to view.
|
||||
|
||||
Params: none.
|
||||
Params: none
|
||||
|
||||
Returns: Bugzilla::Classification objects values.
|
||||
Returns: An array of Bugzilla::Classification objects, sorted by
|
||||
the classification name.
|
||||
|
||||
=item C<get_userlist>
|
||||
|
||||
|
|
|
@ -64,11 +64,8 @@ $vars->{'keyword'} = \@::legal_keywords;
|
|||
$vars->{'resolution'} = \@::legal_resolution;
|
||||
$vars->{'status'} = \@::legal_bug_status;
|
||||
|
||||
# Include lists of products, components, versions, and target milestones.
|
||||
my $selectables = GetSelectableProductHash();
|
||||
foreach my $selectable (keys %$selectables) {
|
||||
$vars->{$selectable} = $selectables->{$selectable};
|
||||
}
|
||||
# Include a list of product objects.
|
||||
$vars->{'products'} = Bugzilla->user->get_selectable_products;
|
||||
|
||||
# Create separate lists of open versus resolved statuses. This should really
|
||||
# be made part of the configuration.
|
||||
|
|
|
@ -265,8 +265,7 @@ $vars->{'openonly'} = $openonly;
|
|||
$vars->{'reverse'} = $reverse;
|
||||
$vars->{'format'} = $cgi->param('format');
|
||||
$vars->{'query_products'} = \@query_products;
|
||||
my @selectable_products = GetSelectableProducts();
|
||||
$vars->{'products'} = \@selectable_products;
|
||||
$vars->{'products'} = Bugzilla->user->get_selectable_products;
|
||||
|
||||
|
||||
my $format = $template->get_format("reports/duplicates",
|
||||
|
|
|
@ -80,21 +80,13 @@ if (!defined $product || $product eq "") {
|
|||
}
|
||||
|
||||
if (!$cgi->param('classification')) {
|
||||
my %classdesc;
|
||||
my %classifications;
|
||||
|
||||
foreach my $c (GetSelectableClassifications()) {
|
||||
$classdesc{$c} = $::classdesc{$c};
|
||||
$classifications{$c} = $::classifications{$c};
|
||||
}
|
||||
my $classifications = Bugzilla->user->get_selectable_classifications();
|
||||
|
||||
my $classification_size = scalar(keys %classdesc);
|
||||
if ($classification_size == 0) {
|
||||
if (scalar(@$classifications) == 0) {
|
||||
ThrowUserError("no_products");
|
||||
}
|
||||
elsif ($classification_size > 1) {
|
||||
$vars->{'classdesc'} = \%classdesc;
|
||||
$vars->{'classifications'} = \%classifications;
|
||||
elsif (scalar(@$classifications) > 1) {
|
||||
$vars->{'classifications'} = $classifications;
|
||||
|
||||
$vars->{'target'} = "enter_bug.cgi";
|
||||
$vars->{'format'} = $cgi->param('format');
|
||||
|
@ -106,7 +98,7 @@ if (!defined $product || $product eq "") {
|
|||
|| ThrowTemplateError($template->error());
|
||||
exit;
|
||||
}
|
||||
$cgi->param(-name => 'classification', -value => (keys %classdesc)[0]);
|
||||
$cgi->param(-name => 'classification', -value => @$classifications[0]->name);
|
||||
}
|
||||
|
||||
my %products;
|
||||
|
|
|
@ -518,113 +518,6 @@ sub GetEnterableProducts {
|
|||
return (@products);
|
||||
}
|
||||
|
||||
|
||||
#
|
||||
# This function returns an alphabetical list of product names to which
|
||||
# the user can enter bugs. If the $by_id parameter is true, also retrieves IDs
|
||||
# and pushes them onto the list as id, name [, id, name...] for easy slurping
|
||||
# into a hash by the calling code.
|
||||
sub GetSelectableProducts {
|
||||
my ($by_id,$by_classification) = @_;
|
||||
|
||||
my $extra_sql = $by_id ? "id, " : "";
|
||||
|
||||
my $extra_from_sql = $by_classification ? " INNER JOIN classifications"
|
||||
. " ON classifications.id = products.classification_id" : "";
|
||||
|
||||
my $query = "SELECT $extra_sql products.name " .
|
||||
"FROM products $extra_from_sql " .
|
||||
"LEFT JOIN group_control_map " .
|
||||
"ON group_control_map.product_id = products.id ";
|
||||
if (Param('useentrygroupdefault')) {
|
||||
$query .= "AND group_control_map.entry != 0 ";
|
||||
} else {
|
||||
$query .= "AND group_control_map.membercontrol = " .
|
||||
CONTROLMAPMANDATORY . " ";
|
||||
}
|
||||
if (%{Bugzilla->user->groups}) {
|
||||
$query .= "AND group_id NOT IN(" .
|
||||
join(',', values(%{Bugzilla->user->groups})) . ") ";
|
||||
}
|
||||
$query .= "WHERE group_id IS NULL ";
|
||||
if ($by_classification) {
|
||||
$query .= "AND classifications.name = ";
|
||||
$query .= SqlQuote($by_classification) . " ";
|
||||
}
|
||||
$query .= "ORDER BY name";
|
||||
PushGlobalSQLState();
|
||||
SendSQL($query);
|
||||
my @products = ();
|
||||
push(@products, FetchSQLData()) while MoreSQLData();
|
||||
PopGlobalSQLState();
|
||||
return (@products);
|
||||
}
|
||||
|
||||
# GetSelectableProductHash
|
||||
# returns a hash containing
|
||||
# legal_products => an enterable product list
|
||||
# legal_(components|versions|milestones) =>
|
||||
# the list of components, versions, and milestones of enterable products
|
||||
# (components|versions|milestones)_by_product
|
||||
# => a hash of component lists for each enterable product
|
||||
# Milestones only get returned if the usetargetmilestones parameter is set.
|
||||
sub GetSelectableProductHash {
|
||||
# The hash of selectable products and their attributes that gets returned
|
||||
# at the end of this function.
|
||||
my $selectables = {};
|
||||
|
||||
my %products = GetSelectableProducts(1);
|
||||
|
||||
$selectables->{legal_products} = [sort values %products];
|
||||
|
||||
# Run queries that retrieve the list of components, versions,
|
||||
# and target milestones (if used) for the selectable products.
|
||||
my @tables = qw(components versions);
|
||||
push(@tables, 'milestones') if Param('usetargetmilestone');
|
||||
|
||||
PushGlobalSQLState();
|
||||
foreach my $table (@tables) {
|
||||
my %values;
|
||||
my %values_by_product;
|
||||
|
||||
if (scalar(keys %products)) {
|
||||
# Why oh why can't we standardize on these names?!?
|
||||
my $fld = ($table eq "components" ? "name" : "value");
|
||||
|
||||
my $query = "SELECT $fld, product_id FROM $table WHERE product_id " .
|
||||
"IN (" . join(",", keys %products) . ") ORDER BY $fld";
|
||||
SendSQL($query);
|
||||
|
||||
while (MoreSQLData()) {
|
||||
my ($name, $product_id) = FetchSQLData();
|
||||
next unless $name;
|
||||
$values{$name} = 1;
|
||||
push @{$values_by_product{$products{$product_id}}}, $name;
|
||||
}
|
||||
}
|
||||
|
||||
$selectables->{"legal_$table"} = [sort keys %values];
|
||||
$selectables->{"${table}_by_product"} = \%values_by_product;
|
||||
}
|
||||
PopGlobalSQLState();
|
||||
|
||||
return $selectables;
|
||||
}
|
||||
|
||||
#
|
||||
# This function returns an alphabetical list of classifications that has products the user can enter bugs.
|
||||
sub GetSelectableClassifications {
|
||||
my @selectable_classes = ();
|
||||
|
||||
foreach my $c (sort keys %::classdesc) {
|
||||
if ( scalar(GetSelectableProducts(0,$c)) > 0) {
|
||||
push(@selectable_classes,$c);
|
||||
}
|
||||
}
|
||||
return (@selectable_classes);
|
||||
}
|
||||
|
||||
|
||||
sub ValidatePassword {
|
||||
# Determines whether or not a password is valid (i.e. meets Bugzilla's
|
||||
# requirements for length and content).
|
||||
|
|
|
@ -66,7 +66,8 @@ if ($cgi->param("GoAheadAndLogIn")) {
|
|||
Bugzilla->login();
|
||||
}
|
||||
|
||||
my $userid = Bugzilla->user->id;
|
||||
my $user = Bugzilla->user;
|
||||
my $userid = $user->id;
|
||||
|
||||
# Backwards compatibility hack -- if there are any of the old QUERY_*
|
||||
# cookies around, and we are logged in, then move them into the database
|
||||
|
@ -219,23 +220,26 @@ GetVersionTable();
|
|||
# if using groups for entry, then we don't want people to see products they
|
||||
# don't have access to. Remove them from the list.
|
||||
|
||||
my @products = ();
|
||||
my @selectable_product_objects = @{$user->get_selectable_products};
|
||||
|
||||
my %component_set;
|
||||
my %version_set;
|
||||
my %milestone_set;
|
||||
foreach my $p (GetSelectableProducts()) {
|
||||
# extract product names
|
||||
my @products = map { $_->name } @selectable_product_objects;
|
||||
|
||||
foreach my $prod_name (@products) {
|
||||
# We build up boolean hashes in the "-set" hashes for each of these things
|
||||
# before making a list because there may be duplicates names across products.
|
||||
push @products, $p;
|
||||
if ($::components{$p}) {
|
||||
foreach my $c (@{$::components{$p}}) {
|
||||
if ($::components{$prod_name}) {
|
||||
foreach my $c (@{$::components{$prod_name}}) {
|
||||
$component_set{$c} = 1;
|
||||
}
|
||||
}
|
||||
foreach my $v (@{$::versions{$p}}) {
|
||||
foreach my $v (@{$::versions{$prod_name}}) {
|
||||
$version_set{$v} = 1;
|
||||
}
|
||||
foreach my $m (@{$::target_milestone{$p}}) {
|
||||
foreach my $m (@{$::target_milestone{$prod_name}}) {
|
||||
$milestone_set{$m} = 1;
|
||||
}
|
||||
}
|
||||
|
@ -296,11 +300,16 @@ $vars->{'product'} = \@products;
|
|||
if (Param('useclassification')) {
|
||||
my @classifications = ();
|
||||
|
||||
foreach my $c (GetSelectableClassifications()) {
|
||||
my $class = $user->get_selectable_classifications;
|
||||
foreach my $c (@$class) {
|
||||
# Extract the name of products being in this classification.
|
||||
my @prod_in_class
|
||||
= grep { $_->classification_id == $c->id } @selectable_product_objects;
|
||||
@prod_in_class = map { $_->name } @prod_in_class;
|
||||
# Create hash to hold attributes for each classification.
|
||||
my %classification = (
|
||||
'name' => $c,
|
||||
'products' => [ GetSelectableProducts(0,$c) ]
|
||||
'name' => $c->name,
|
||||
'products' => \@prod_in_class
|
||||
);
|
||||
# Assign hash back to classification array.
|
||||
push @classifications, \%classification;
|
||||
|
|
|
@ -54,7 +54,7 @@ use Bugzilla;
|
|||
|
||||
# If we're using bug groups for products, we should apply those restrictions
|
||||
# to viewing reports, as well. Time to check the login in that case.
|
||||
Bugzilla->login();
|
||||
my $user = Bugzilla->login();
|
||||
|
||||
GetVersionTable();
|
||||
|
||||
|
@ -66,7 +66,8 @@ my $template = Bugzilla->template;
|
|||
# We only want those products that the user has permissions for.
|
||||
my @myproducts;
|
||||
push( @myproducts, "-All-");
|
||||
push( @myproducts, GetSelectableProducts());
|
||||
# Extract product names from objects and add them to the list.
|
||||
push( @myproducts, map { $_->name } @{$user->get_selectable_products} );
|
||||
|
||||
if (! defined $cgi->param('product')) {
|
||||
|
||||
|
|
|
@ -27,28 +27,26 @@
|
|||
# Make it harder for us to do dangerous things in Perl.
|
||||
use strict;
|
||||
|
||||
# Include the Bugzilla CGI and general utility library.
|
||||
use lib qw(.);
|
||||
require "globals.pl";
|
||||
use Bugzilla;
|
||||
# Use Bugzilla's Request module which contains utilities for handling requests.
|
||||
use Bugzilla::Flag;
|
||||
use Bugzilla::FlagType;
|
||||
|
||||
# use Bugzilla's User module which contains utilities for handling users.
|
||||
use Bugzilla::User;
|
||||
|
||||
use vars qw($template $vars @legal_product @legal_components %components);
|
||||
use vars qw($template $vars);
|
||||
|
||||
# Make sure the user is logged in.
|
||||
Bugzilla->login();
|
||||
my $user = Bugzilla->login();
|
||||
my $userid = $user->id;
|
||||
|
||||
my $cgi = Bugzilla->cgi;
|
||||
|
||||
|
||||
################################################################################
|
||||
# Main Body Execution
|
||||
################################################################################
|
||||
|
||||
my $cgi = Bugzilla->cgi;
|
||||
|
||||
my $fields;
|
||||
$fields->{'requester'}->{'type'} = 'single';
|
||||
# If the user doesn't restrict his search to requests from the wind
|
||||
|
@ -116,17 +114,17 @@ sub queue {
|
|||
LEFT JOIN bug_group_map AS bgmap
|
||||
ON bgmap.bug_id = bugs.bug_id
|
||||
AND bgmap.group_id NOT IN (" .
|
||||
join(', ', (-1, values(%{Bugzilla->user->groups}))) . ")
|
||||
join(', ', (-1, values(%{$user->groups}))) . ")
|
||||
LEFT JOIN cc AS ccmap
|
||||
ON ccmap.who = $::userid
|
||||
AND ccmap.bug_id = bugs.bug_id
|
||||
ON ccmap.who = $userid
|
||||
AND ccmap.bug_id = bugs.bug_id
|
||||
" .
|
||||
|
||||
# Weed out bug the user does not have access to
|
||||
" WHERE ((bgmap.group_id IS NULL) OR
|
||||
(ccmap.who IS NOT NULL AND cclist_accessible = 1) OR
|
||||
(bugs.reporter = $::userid AND bugs.reporter_accessible = 1) OR
|
||||
(bugs.assigned_to = $::userid))";
|
||||
(bugs.reporter = $userid AND bugs.reporter_accessible = 1) OR
|
||||
(bugs.assigned_to = $userid))";
|
||||
|
||||
# Non-deleted flags only
|
||||
$query .= " AND flags.is_active = 1 ";
|
||||
|
@ -279,15 +277,7 @@ sub queue {
|
|||
SendSQL("SELECT DISTINCT(name) FROM flagtypes ORDER BY name");
|
||||
push(@types, FetchOneColumn()) while MoreSQLData();
|
||||
|
||||
# products and components and the function used to modify the components
|
||||
# menu when the products menu changes; used by the template to populate
|
||||
# the menus and keep the components menu consistent with the products menu
|
||||
GetVersionTable();
|
||||
my $selectable = GetSelectableProductHash();
|
||||
$vars->{'products'} = $selectable->{legal_products};
|
||||
$vars->{'components'} = $selectable->{legal_components};
|
||||
$vars->{'components_by_product'} = $selectable->{components_by_product};
|
||||
|
||||
$vars->{'products'} = $user->get_selectable_products;
|
||||
$vars->{'excluded_columns'} = \@excluded_columns;
|
||||
$vars->{'group_field'} = $form_group;
|
||||
$vars->{'requests'} = \@requests;
|
||||
|
|
|
@ -73,10 +73,10 @@ var component = new Object();
|
|||
var version = new Object();
|
||||
var target_milestone = new Object();
|
||||
|
||||
[% FOREACH p = legal_products %]
|
||||
component['[% p FILTER js %]'] = [ [% FOREACH x = components_by_product.$p %]'[% x FILTER js %]', [% END %] ];
|
||||
version['[% p FILTER js %]'] = [ [% FOREACH x = versions_by_product.$p %]'[% x FILTER js %]', [% END %] ];
|
||||
target_milestone['[% p FILTER js %]'] = [ [% FOREACH x = milestones_by_product.$p %]'[% x FILTER js %]', [% END %] ];
|
||||
[% FOREACH p = products %]
|
||||
component['[% p.name FILTER js %]'] = [ [% FOREACH x = p.components %]'[% x.name FILTER js %]', [% END %] ];
|
||||
version['[% p.name FILTER js %]'] = [ [% FOREACH x = p.versions %]'[% x.name FILTER js %]', [% END %] ];
|
||||
target_milestone['[% p.name FILTER js %]'] = [ [% FOREACH x = p.milestones %]'[% x.name FILTER js %]', [% END %] ];
|
||||
[% END %]
|
||||
|
||||
// Product and Component Exceptions
|
||||
|
|
|
@ -105,23 +105,23 @@
|
|||
|
||||
<bz:products>
|
||||
<Seq>
|
||||
[% FOREACH product = legal_products %]
|
||||
[% FOREACH product = products %]
|
||||
<li>
|
||||
<bz:product rdf:about="[% Param('urlbase') %]product.cgi?name=[% product FILTER uri %]">
|
||||
<bz:name>[% product FILTER html %]</bz:name>
|
||||
<bz:product rdf:about="[% Param('urlbase') %]product.cgi?name=[% product.name FILTER uri %]">
|
||||
<bz:name>[% product.name FILTER html %]</bz:name>
|
||||
|
||||
<bz:components>
|
||||
<Seq>
|
||||
[% FOREACH component = components_by_product.$product %]
|
||||
<li resource="[% Param('urlbase') %]component.cgi?name=[% component FILTER uri %]"/>
|
||||
[% FOREACH component = product.components %]
|
||||
<li resource="[% Param('urlbase') %]component.cgi?name=[% component.name FILTER uri %]"/>
|
||||
[% END %]
|
||||
</Seq>
|
||||
</bz:components>
|
||||
|
||||
<bz:versions>
|
||||
<Seq>
|
||||
[% FOREACH version = versions_by_product.$product %]
|
||||
<li resource="[% Param('urlbase') %]version.cgi?name=[% version FILTER uri %]"/>
|
||||
[% FOREACH version = product.versions %]
|
||||
<li resource="[% Param('urlbase') %]version.cgi?name=[% version.name FILTER uri %]"/>
|
||||
[% END %]
|
||||
</Seq>
|
||||
</bz:versions>
|
||||
|
@ -129,8 +129,8 @@
|
|||
[% IF Param('usetargetmilestone') %]
|
||||
<bz:target_milestones>
|
||||
<Seq>
|
||||
[% FOREACH milestone = milestones_by_product.$product %]
|
||||
<li resource="[% Param('urlbase') %]milestone.cgi?name=[% milestone FILTER uri %]"/>
|
||||
[% FOREACH milestone = product.milestones %]
|
||||
<li resource="[% Param('urlbase') %]milestone.cgi?name=[% milestone.name FILTER uri %]"/>
|
||||
[% END %]
|
||||
</Seq>
|
||||
</bz:target_milestones>
|
||||
|
@ -144,24 +144,28 @@
|
|||
|
||||
<bz:components>
|
||||
<Seq>
|
||||
[% FOREACH item = legal_components %]
|
||||
<li>
|
||||
<bz:component rdf:about="[% Param('urlbase') %]component.cgi?name=[% item FILTER uri %]">
|
||||
<bz:name>[% item FILTER html %]</bz:name>
|
||||
</bz:component>
|
||||
</li>
|
||||
[% FOREACH product = products %]
|
||||
[% FOREACH component = product.components %]
|
||||
<li>
|
||||
<bz:component rdf:about="[% Param('urlbase') %]component.cgi?name=[% component.name FILTER uri %]">
|
||||
<bz:name>[% component.name FILTER html %]</bz:name>
|
||||
</bz:component>
|
||||
</li>
|
||||
[% END %]
|
||||
[% END %]
|
||||
</Seq>
|
||||
</bz:components>
|
||||
|
||||
<bz:versions>
|
||||
<Seq>
|
||||
[% FOREACH item = legal_versions %]
|
||||
<li>
|
||||
<bz:version rdf:about="[% Param('urlbase') %]version.cgi?name=[% item FILTER uri %]">
|
||||
<bz:name>[% item FILTER html %]</bz:name>
|
||||
</bz:version>
|
||||
</li>
|
||||
[% FOREACH product = products %]
|
||||
[% FOREACH version = product.versions %]
|
||||
<li>
|
||||
<bz:version rdf:about="[% Param('urlbase') %]version.cgi?name=[% version.name FILTER uri %]">
|
||||
<bz:name>[% version.name FILTER html %]</bz:name>
|
||||
</bz:version>
|
||||
</li>
|
||||
[% END %]
|
||||
[% END %]
|
||||
</Seq>
|
||||
</bz:versions>
|
||||
|
@ -169,12 +173,14 @@
|
|||
[% IF Param('usetargetmilestone') %]
|
||||
<bz:target_milestones>
|
||||
<Seq>
|
||||
[% FOREACH item = legal_milestones %]
|
||||
<li>
|
||||
<bz:target_milestone rdf:about="[% Param('urlbase') %]milestone.cgi?name=[% item FILTER uri %]">
|
||||
<bz:name>[% item FILTER html %]</bz:name>
|
||||
</bz:target_milestone>
|
||||
</li>
|
||||
[% FOREACH product = products %]
|
||||
[% FOREACH milestone = product.milestones %]
|
||||
<li>
|
||||
<bz:target_milestone rdf:about="[% Param('urlbase') %]milestone.cgi?name=[% milestone.name FILTER uri %]">
|
||||
<bz:name>[% milestone.name FILTER html %]</bz:name>
|
||||
</bz:target_milestone>
|
||||
</li>
|
||||
[% END %]
|
||||
[% END %]
|
||||
</Seq>
|
||||
</bz:target_milestones>
|
||||
|
|
|
@ -244,7 +244,7 @@
|
|||
],
|
||||
|
||||
'global/choose-classification.html.tmpl' => [
|
||||
'classdesc.$p',
|
||||
'class.description',
|
||||
],
|
||||
|
||||
'global/choose-product.html.tmpl' => [
|
||||
|
|
|
@ -18,8 +18,8 @@
|
|||
#%]
|
||||
|
||||
[%# INTERFACE:
|
||||
# classdesc: hash. May be empty. The hash keys are the classifications, and the values
|
||||
# are their descriptions.
|
||||
# classifications: an array of classification objects containing
|
||||
# at least one product accessible by the user.
|
||||
#%]
|
||||
|
||||
[% IF target == "enter_bug.cgi" %]
|
||||
|
@ -45,21 +45,19 @@
|
|||
</tr>
|
||||
[% END %]
|
||||
|
||||
[% FOREACH p = classdesc.keys.sort %]
|
||||
[% IF classifications.$p.size > 0 %]
|
||||
[% FOREACH class = classifications %]
|
||||
<tr>
|
||||
<th align="right" valign="top">
|
||||
<a href="[% target FILTER url_quote %]?classification=[% p FILTER url_quote -%]
|
||||
<a href="[% target FILTER url_quote %]?classification=[% class.name FILTER url_quote -%]
|
||||
[%- IF cloned_bug_id %]&cloned_bug_id=[% cloned_bug_id FILTER url_quote %][% END -%]
|
||||
[%- IF format %]&format=[% format FILTER url_quote %][% END %]">
|
||||
[% p FILTER html %]</a>:
|
||||
[% class.name FILTER html %]</a>:
|
||||
</th>
|
||||
|
||||
[% IF classdesc.$p %]
|
||||
<td valign="top"> [% classdesc.$p %]</td>
|
||||
[% IF class.description %]
|
||||
<td valign="top"> [% class.description %]</td>
|
||||
[% END %]
|
||||
</tr>
|
||||
[% END %]
|
||||
[% END %]
|
||||
|
||||
</table>
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
#%]
|
||||
|
||||
[%# INTERFACE:
|
||||
# products: list of strings. The products this user can see.
|
||||
# products: an array of product objects this user can see.
|
||||
#
|
||||
# sortby: string. the column on which we are sorting the buglist.
|
||||
# reverse: boolean. True if we are reversing the current sort.
|
||||
|
@ -84,9 +84,9 @@
|
|||
<td rowspan="4" valign="top">
|
||||
<select name="product" size="5" multiple="multiple">
|
||||
[% FOREACH p = products %]
|
||||
<option name="[% p FILTER html %]"
|
||||
[% " selected" IF lsearch(query_products, p) != -1 %]
|
||||
>[% p FILTER html %]</option>
|
||||
<option name="[% p.name FILTER html %]"
|
||||
[% " selected" IF lsearch(query_products, p.name) != -1 %]
|
||||
>[% p.name FILTER html %]</option>
|
||||
[% END %]
|
||||
</select>
|
||||
</td>
|
||||
|
|
|
@ -30,9 +30,9 @@
|
|||
var first_load = 1; // is this the first time we load the page?
|
||||
var last_sel = []; // caches last selection
|
||||
var cpts = new Array();
|
||||
[% FOREACH p = products %]
|
||||
cpts['[% p FILTER js %]'] = [
|
||||
[%- FOREACH item = components_by_product.$p %]'[% item FILTER js %]'[% ", " UNLESS loop.last %] [%- END -%] ];
|
||||
[% FOREACH prod = products %]
|
||||
cpts['[% prod.name FILTER js %]'] = [
|
||||
[%- FOREACH comp = prod.components %]'[% comp.name FILTER js %]'[% ", " UNLESS loop.last %] [%- END -%] ];
|
||||
[% END %]
|
||||
[% END %]
|
||||
|
||||
|
@ -58,9 +58,10 @@
|
|||
<td>
|
||||
<select name="product" onchange="selectProduct(this.form, 'product', 'component', 'Any');">
|
||||
<option value="">Any</option>
|
||||
[% FOREACH item = products %]
|
||||
<option value="[% item FILTER html %]"
|
||||
[% "selected" IF cgi.param('product') == item %]>[% item FILTER html %]</option>
|
||||
[% FOREACH prod = products %]
|
||||
<option value="[% prod.name FILTER html %]"
|
||||
[% "selected" IF cgi.param('product') == prod.name %]>
|
||||
[% prod.name FILTER html %]</option>
|
||||
[% END %]
|
||||
</select>
|
||||
</td>
|
||||
|
@ -92,9 +93,11 @@
|
|||
<td>
|
||||
<select name="component">
|
||||
<option value="">Any</option>
|
||||
[% FOREACH item = components %]
|
||||
<option value="[% item FILTER html %]" [% "selected" IF cgi.param('component') == item %]>
|
||||
[% item FILTER html %]</option>
|
||||
[% FOREACH prod = products %]
|
||||
[% FOREACH comp = prod.components %]
|
||||
<option value="[% comp.name FILTER html %]" [% "selected" IF cgi.param('component') == comp.name %]>
|
||||
[% comp.name FILTER html %]</option>
|
||||
[% END %]
|
||||
[% END %]
|
||||
</select>
|
||||
</td>
|
||||
|
|
Загрузка…
Ссылка в новой задаче