diff options
-rw-r--r-- | Bugzilla/BugMail.pm | 4 | ||||
-rwxr-xr-x | contrib/bug_email.pl | 52 | ||||
-rwxr-xr-x | editflagtypes.cgi | 52 | ||||
-rw-r--r-- | globals.pl | 22 | ||||
-rwxr-xr-x | post_bug.cgi | 43 | ||||
-rwxr-xr-x | process_bug.cgi | 62 | ||||
-rwxr-xr-x | request.cgi | 27 | ||||
-rw-r--r-- | template/en/default/global/code-error.html.tmpl | 18 |
8 files changed, 107 insertions, 173 deletions
diff --git a/Bugzilla/BugMail.pm b/Bugzilla/BugMail.pm index b2613466a..74e1145a7 100644 --- a/Bugzilla/BugMail.pm +++ b/Bugzilla/BugMail.pm @@ -38,6 +38,7 @@ use Bugzilla::Constants; use Bugzilla::Config qw(:DEFAULT $datadir); use Bugzilla::Util; use Bugzilla::Bug; +use Bugzilla::Component; use Date::Parse; use Date::Format; @@ -141,7 +142,8 @@ sub ProcessOneBug { undef, $id)}; $values{product} = &::get_product_name($values{product_id}); - $values{component} = &::get_component_name($values{component_id}); + my $component = new Bugzilla::Component($values{component_id}); + $values{component} = $component->name; my ($start, $end) = ($values{start}, $values{end}); diff --git a/contrib/bug_email.pl b/contrib/bug_email.pl index 15fdaa718..141136a87 100755 --- a/contrib/bug_email.pl +++ b/contrib/bug_email.pl @@ -38,7 +38,7 @@ # # You need to work with bug_email.pl the MIME::Parser installed. # -# $Id: bug_email.pl,v 1.34 2006/05/14 19:12:13 lpsolit%gmail.com Exp $ +# $Id: bug_email.pl,v 1.35 2006/05/29 17:24:54 lpsolit%gmail.com Exp $ ############################################################### # 02/12/2000 (SML) @@ -96,6 +96,8 @@ use lib "../"; use Bugzilla::Constants; use Bugzilla::BugMail; use Bugzilla::User; +use Bugzilla::Product; +use Bugzilla::Component; my @mailerrors = (); # Buffer for Errors in the mail my @mailwarnings = (); # Buffer for Warnings found in the mail @@ -202,34 +204,6 @@ sub CheckPermissions { } ############################################################### -# Check if product is valid. -sub CheckProduct { - my $Product = shift; - my $dbh = Bugzilla->dbh; - my $prod_name = $dbh->selectrow_array(q{SELECT name - FROM products - WHERE name = ?}, undef, $Product); - return $prod_name || ""; -} - -############################################################### -# Check if component is valid for product. -sub CheckComponent { - my $Product = shift; - my $Component = shift; - my $dbh = Bugzilla->dbh; - - my $comp_name = $dbh->selectrow_array(q{SELECT components.name - FROM components - INNER JOIN products - ON components.product_id = products.id - WHERE products.name= ? - AND components.name= ?}, - undef, $Product, $Component); - return $comp_name || ""; -} - -############################################################### # Check if component is valid for product. sub CheckVersion { my $Product = shift; @@ -812,10 +786,14 @@ if (Param("useqacontact")) { # depends on the product ! # => first check product ! # Product +my $product; my $all_products; # set to the default product. If the default product is empty, this has no effect my $Product = $DEFAULT_PRODUCT; -$Product = CheckProduct( $Control{'product'} ) if( defined( $Control{ 'product'} )); +if (defined($Control{ 'product'})) { + $product = new Bugzilla::Product({'name' => $Control{'product'}}); + $Product = $product ? $product->name : ""; +} if ( $Product eq "" ) { my $Text = "You didn't send a value for the required key \@product !\n\n"; @@ -843,12 +821,15 @@ $Control{'product'} = $Product; # # set to the default component. If the default component is empty, this has no effect +my $component; my $Component = $DEFAULT_COMPONENT; -if( defined( $Control{'component' } )) { - $Component = CheckComponent( $Control{'product'}, $Control{'component'} ); +if (defined($Control{'component'})) { + $component = new Bugzilla::Component({'product_id' => $product->id, + 'name' => $Control{'component'}}); + $Component = $component ? $component->name : ""; } - + if ( $Component eq "" ) { my $Text = "You did not send a value for the required key \@component!\n\n"; @@ -1091,10 +1072,9 @@ END if( $field eq "groupset" ) { push (@values, $Control{$field}); } elsif ( $field eq 'product' ) { - push (@values, get_product_id($Control{$field})); + push (@values, $product->id); } elsif ( $field eq 'component' ) { - push (@values, get_component_id(get_product_id($Control{'product'}), - $Control{$field})); + push (@values, $component->id); } else { push (@values, $Control{$field}); } diff --git a/editflagtypes.cgi b/editflagtypes.cgi index bcab4e189..8f6bf601f 100755 --- a/editflagtypes.cgi +++ b/editflagtypes.cgi @@ -19,6 +19,7 @@ # Rights Reserved. # # Contributor(s): Myk Melez <myk@mozilla.org> +# Frédéric Buclin <LpSolit@gmail.com> ################################################################################ # Script Initialization @@ -39,6 +40,7 @@ use Bugzilla::FlagType; use Bugzilla::Group; use Bugzilla::Util; use Bugzilla::Product; +use Bugzilla::Component; my $template = Bugzilla->template; my $vars = {}; @@ -51,8 +53,6 @@ $user->in_group('editcomponents') object => "flagtypes"}); my $cgi = Bugzilla->cgi; -my $product_id; -my $component_id; ################################################################################ # Main Body Execution @@ -190,15 +190,17 @@ sub processCategoryChange { my @inclusions = $cgi->param('inclusions'); my @exclusions = $cgi->param('exclusions'); if ($categoryAction eq 'include') { - validateProduct(); - validateComponent(); - my $category = ($product_id || 0) . ":" . ($component_id || 0); + my $product = validateProduct(scalar $cgi->param('product')); + my $component = validateComponent($product, scalar $cgi->param('component')); + my $category = ($product ? $product->id : 0) . ":" . + ($component ? $component->id : 0); push(@inclusions, $category) unless grep($_ eq $category, @inclusions); } elsif ($categoryAction eq 'exclude') { - validateProduct(); - validateComponent(); - my $category = ($product_id || 0) . ":" . ($component_id || 0); + my $product = validateProduct(scalar $cgi->param('product')); + my $component = validateComponent($product, scalar $cgi->param('component')); + my $category = ($product ? $product->id : 0) . ":" . + ($component ? $component->id : 0); push(@exclusions, $category) unless grep($_ eq $category, @exclusions); } elsif ($categoryAction eq 'removeInclusion') { @@ -249,11 +251,16 @@ sub processCategoryChange { sub clusion_array_to_hash { my $array = shift; my %hash; + my %components; foreach my $ids (@$array) { trick_taint($ids); my ($product_id, $component_id) = split(":", $ids); my $product_name = get_product_name($product_id) || "__Any__"; - my $component_name = get_component_name($component_id) || "__Any__"; + my $component_name = "__Any__"; + if ($component_id) { + $components{$component_id} ||= new Bugzilla::Component($component_id); + $component_name = $components{$component_id}->name; + } $hash{"$product_name:$component_name"} = $ids; } return %hash; @@ -531,27 +538,22 @@ sub validateCCList { } sub validateProduct { - return if !$cgi->param('product'); - - $product_id = get_product_id($cgi->param('product')); - - defined($product_id) - || ThrowCodeError("flag_type_product_nonexistent", - { product => $cgi->param('product') }); + my $product_name = shift; + return unless $product_name; + + my $product = Bugzilla::Product::check_product($product_name); + return $product; } sub validateComponent { - return if !$cgi->param('component'); - - $product_id + my ($product, $component_name) = @_; + return unless $component_name; + + ($product && $product->id) || ThrowCodeError("flag_type_component_without_product"); - - $component_id = get_component_id($product_id, $cgi->param('component')); - defined($component_id) - || ThrowCodeError("flag_type_component_nonexistent", - { product => $cgi->param('product'), - name => $cgi->param('component') }); + my $component = Bugzilla::Component::check_component($product, $component_name); + return $component; } sub validateSortKey { diff --git a/globals.pl b/globals.pl index bde05517b..9d47c6d78 100644 --- a/globals.pl +++ b/globals.pl @@ -218,28 +218,6 @@ sub get_product_name { return $prod; } -sub get_component_id { - my ($prod_id, $comp) = @_; - return undef unless ($prod_id && ($prod_id =~ /^\d+$/)); - PushGlobalSQLState(); - SendSQL("SELECT id FROM components " . - "WHERE product_id = $prod_id AND name = " . SqlQuote($comp)); - my ($comp_id) = FetchSQLData(); - PopGlobalSQLState(); - return $comp_id; -} - -sub get_component_name { - my ($comp_id) = @_; - die "non-numeric comp_id '$comp_id' passed to get_component_name" - unless ($comp_id =~ /^\d+$/); - PushGlobalSQLState(); - SendSQL("SELECT name FROM components WHERE id = $comp_id"); - my ($comp) = FetchSQLData(); - PopGlobalSQLState(); - return $comp; -} - # Returns a list of all the legal values for a field that has a # list of legal values, like rep_platform or resolution. sub get_legal_field_values { diff --git a/post_bug.cgi b/post_bug.cgi index 273117c6b..4258251b5 100755 --- a/post_bug.cgi +++ b/post_bug.cgi @@ -95,16 +95,14 @@ ValidateComment($comment); # Check that the product exists and that the user # is allowed to enter bugs into this product. -my $product = $cgi->param('product'); -$user->can_enter_product($product, 1); +$user->can_enter_product(scalar $cgi->param('product'), 1); -my $prod_obj = new Bugzilla::Product({name => $product}); -my $product_id = $prod_obj->id; +my $product = Bugzilla::Product::check_product(scalar $cgi->param('product')); # Set cookies if (defined $cgi->param('product')) { if (defined $cgi->param('version')) { - $cgi->send_cookie(-name => "VERSION-$product", + $cgi->send_cookie(-name => "VERSION-" . $product->name, -value => $cgi->param('version'), -expires => "Fri, 01-Jan-2038 00:00:00 GMT"); } @@ -123,9 +121,8 @@ if (defined $cgi->param('maketemplate')) { umask 0; # Some sanity checking -my $component_id = get_component_id($product_id, - scalar($cgi->param('component'))); -$component_id || ThrowUserError("require_component"); +$cgi->param('component') || ThrowUserError("require_component"); +my $component = Bugzilla::Component::check_component($product, scalar $cgi->param('component')); # Set the parameter to itself, but cleaned up $cgi->param('short_desc', clean_text($cgi->param('short_desc'))); @@ -151,7 +148,7 @@ if (!UserInGroup("editbugs") || $cgi->param('assigned_to') eq "") { my $initialowner = $dbh->selectrow_array(q{SELECT initialowner FROM components WHERE id = ?}, - undef, $component_id); + undef, $component->id); $cgi->param(-name => 'assigned_to', -value => $initialowner); } else { $cgi->param(-name => 'assigned_to', @@ -180,7 +177,7 @@ if (Param("useqacontact")) { ($qa_contact) = $dbh->selectrow_array(q{SELECT initialqacontact FROM components WHERE id = ?}, - undef, $component_id); + undef, $component->id); } else { $qa_contact = login_to_id(trim($cgi->param('qa_contact')), THROW_ERROR); } @@ -202,20 +199,18 @@ if (UserInGroup("editbugs") || UserInGroup("canconfirm")) { my $votestoconfirm = $dbh->selectrow_array(q{SELECT votestoconfirm FROM products WHERE id = ?}, - undef, $product_id); + undef, $product->id); if (!$votestoconfirm) { $cgi->param(-name => 'bug_status', -value => "NEW"); } } -trick_taint($product); - if (!defined $cgi->param('target_milestone')) { my $defaultmilestone = $dbh->selectrow_array(q{SELECT defaultmilestone FROM products WHERE name = ?}, - undef, $product); + undef, $product->name); $cgi->param(-name => 'target_milestone', -value => $defaultmilestone); } @@ -226,19 +221,15 @@ if (!Param('letsubmitterchoosepriority')) { GetVersionTable(); # Some more sanity checking -check_field('product', scalar $cgi->param('product'), - [map($_->name, Bugzilla::Product::get_all_products())]); check_field('rep_platform', scalar $cgi->param('rep_platform'), \@::legal_platform); check_field('bug_severity', scalar $cgi->param('bug_severity'), \@::legal_severity); check_field('priority', scalar $cgi->param('priority'), \@::legal_priority); check_field('op_sys', scalar $cgi->param('op_sys'), \@::legal_opsys); check_field('bug_status', scalar $cgi->param('bug_status'), ['UNCONFIRMED', 'NEW']); check_field('version', scalar $cgi->param('version'), - [map($_->name, @{$prod_obj->versions})]); -check_field('component', scalar $cgi->param('component'), - [map($_->name, @{$prod_obj->components})]); + [map($_->name, @{$product->versions})]); check_field('target_milestone', scalar $cgi->param('target_milestone'), - [map($_->name, @{$prod_obj->milestones})]); + [map($_->name, @{$product->milestones})]); foreach my $field_name ('assigned_to', 'bug_file_loc', 'comment') { defined($cgi->param($field_name)) @@ -255,9 +246,9 @@ foreach my $field (@bug_fields) { } } -$cgi->param(-name => 'product_id', -value => $product_id); +$cgi->param(-name => 'product_id', -value => $product->id); push(@used_fields, "product_id"); -$cgi->param(-name => 'component_id', -value => $component_id); +$cgi->param(-name => 'component_id', -value => $component->id); push(@used_fields, "component_id"); my %ccids; @@ -304,7 +295,7 @@ if (Param("strict_isolation")) { } foreach my $pid (keys %related_users) { my $related_user = Bugzilla::User->new($pid); - if (!$related_user->can_edit_product($product_id)) { + if (!$related_user->can_edit_product($product->id)) { push (@blocked_users, $related_user->login); } } @@ -312,7 +303,7 @@ if (Param("strict_isolation")) { ThrowUserError("invalid_user_group", {'users' => \@blocked_users, 'new' => 1, - 'product' => $product + 'product' => $product->name }); } } @@ -416,7 +407,7 @@ foreach my $b (grep(/^bit-\d*$/, $cgi->param())) { my ($permit) = $user->in_group_id($v); if (!$permit) { my $othercontrol = $dbh->selectrow_array($sth_othercontrol, - undef, ($v, $product_id)); + undef, ($v, $product->id)); $permit = (($othercontrol == CONTROLMAPSHOWN) || ($othercontrol == CONTROLMAPDEFAULT)); } @@ -435,7 +426,7 @@ my $groups = $dbh->selectall_arrayref(q{ AND product_id = ? WHERE isbuggroup != 0 AND isactive != 0 - ORDER BY description}, undef, $product_id); + ORDER BY description}, undef, $product->id); foreach my $group (@$groups) { my ($id, $groupname, $membercontrol, $othercontrol) = @$group; diff --git a/process_bug.cgi b/process_bug.cgi index e92ec5acf..7c52254ee 100755 --- a/process_bug.cgi +++ b/process_bug.cgi @@ -57,6 +57,7 @@ use Bugzilla::User; use Bugzilla::Util; use Bugzilla::Field; use Bugzilla::Product; +use Bugzilla::Component; use Bugzilla::Keyword; # Use the Flag module to modify flag data if the user set flags. @@ -944,20 +945,16 @@ foreach my $field (Bugzilla->custom_field_names) { } } - -my $prod_id; +my $product; my $prod_changed; my @newprod_ids; if ($cgi->param('product') ne $cgi->param('dontchange')) { - $prod_id = get_product_id($cgi->param('product')); - $prod_id || - ThrowUserError("invalid_product_name", - {product => $cgi->param('product')}); - + $product = Bugzilla::Product::check_product(scalar $cgi->param('product')); + DoComma(); $::query .= "product_id = ?"; - push(@values, $prod_id); - @newprod_ids = ($prod_id); + push(@values, $product->id); + @newprod_ids = ($product->id); $prod_changed = 1; } else { @newprod_ids = @{$dbh->selectcol_arrayref("SELECT DISTINCT product_id @@ -966,25 +963,23 @@ if ($cgi->param('product') ne $cgi->param('dontchange')) { join(',', @idlist) . ")")}; if (scalar(@newprod_ids) == 1) { - ($prod_id) = @newprod_ids; + $product = Bugzilla::Product::check_product($newprod_ids[0]); } } -my $comp_id; +my $component; if ($cgi->param('component') ne $cgi->param('dontchange')) { if (scalar(@newprod_ids) > 1) { ThrowUserError("no_component_change_for_multiple_products"); } - $comp_id = get_component_id($prod_id, - $cgi->param('component')); - $comp_id || ThrowCodeError("invalid_component", - {name => $cgi->param('component'), - product => $cgi->param('product')}); - - $cgi->param('component_id', $comp_id); + $component = + Bugzilla::Component::check_component($product, scalar $cgi->param('component')); + + # This parameter is required later when checking fields the user can change. + $cgi->param('component_id', $component->id); DoComma(); $::query .= "component_id = ?"; - push(@values, $comp_id); + push(@values, $component->id); } # If this installation uses bug aliases, and the user is changing the alias, @@ -1447,14 +1442,14 @@ if ($prod_changed && Param("strict_isolation")) { my $sth_bug = $dbh->prepare("SELECT assigned_to, qa_contact FROM bugs WHERE bug_id = ?"); - my $prod_name = get_product_name($prod_id); + foreach my $id (@idlist) { $sth_cc->execute($id); my @blocked_cc = (); while (my ($pid) = $sth_cc->fetchrow_array) { $usercache{$pid} ||= Bugzilla::User->new($pid); my $cc_user = $usercache{$pid}; - if (!$cc_user->can_edit_product($prod_id)) { + if (!$cc_user->can_edit_product($product->id)) { push (@blocked_cc, $cc_user->login); } } @@ -1462,28 +1457,28 @@ if ($prod_changed && Param("strict_isolation")) { ThrowUserError('invalid_user_group', {'users' => \@blocked_cc, 'bug_id' => $id, - 'product' => $prod_name}); + 'product' => $product->name}); } $sth_bug->execute($id); my ($assignee, $qacontact) = $sth_bug->fetchrow_array; if (!$assignee_checked) { $usercache{$assignee} ||= Bugzilla::User->new($assignee); my $assign_user = $usercache{$assignee}; - if (!$assign_user->can_edit_product($prod_id)) { + if (!$assign_user->can_edit_product($product->id)) { ThrowUserError('invalid_user_group', {'users' => $assign_user->login, 'bug_id' => $id, - 'product' => $prod_name}); + 'product' => $product->name}); } } if (!$qacontact_checked && $qacontact) { $usercache{$qacontact} ||= Bugzilla::User->new($qacontact); my $qa_user = $usercache{$qacontact}; - if (!$qa_user->can_edit_product($prod_id)) { + if (!$qa_user->can_edit_product($product->id)) { ThrowUserError('invalid_user_group', {'users' => $qa_user->login, 'bug_id' => $id, - 'product' => $prod_name}); + 'product' => $product->name}); } } } @@ -1498,13 +1493,13 @@ if ($prod_changed && Param("strict_isolation")) { foreach my $id (@idlist) { my $query = $basequery; my @bug_values = @values; - my $bug_obj = new Bugzilla::Bug($id, $whoid); + my $old_bug_obj = new Bugzilla::Bug($id, $whoid); if ($cgi->param('knob') eq 'reassignbycomponent') { # We have to check whether the bug is moved to another product - # and/or component before reassigning. If $comp_id is defined, + # and/or component before reassigning. If $component is defined, # use it; else use the product/component the bug is already in. - my $new_comp_id = $comp_id || $bug_obj->{'component_id'}; + my $new_comp_id = $component ? $component->id : $old_bug_obj->{'component_id'}; $assignee = $dbh->selectrow_array('SELECT initialowner FROM components WHERE components.id = ?', @@ -1540,7 +1535,7 @@ foreach my $id (@idlist) { "keyworddefs READ", "groups READ", "attachments READ", "group_control_map AS oldcontrolmap READ", "group_control_map AS newcontrolmap READ", - "group_control_map READ", "email_setting READ"); + "group_control_map READ", "email_setting READ", "classifications READ"); # It may sound crazy to set %formhash for each bug as $cgi->param() # will not change, but %formhash is modified below and we prefer @@ -1585,7 +1580,7 @@ foreach my $id (@idlist) { my $vars; if ($col eq 'component_id') { # Display the component name - $vars->{'oldvalue'} = get_component_name($oldhash{$col}); + $vars->{'oldvalue'} = $old_bug_obj->component; $vars->{'newvalue'} = $cgi->param('component'); $vars->{'field'} = 'component'; } elsif ($col eq 'assigned_to' || $col eq 'qa_contact') { @@ -2048,6 +2043,7 @@ foreach my $id (@idlist) { # and then generate any necessary bug activity entries by seeing # what has changed since before we wrote out the new values. # + my $new_bug_obj = new Bugzilla::Bug($id, $whoid); my @newvalues = SnapShotBug($id); my %newhash; $i = 0; @@ -2085,8 +2081,8 @@ foreach my $id (@idlist) { $col = 'product'; } if ($col eq 'component_id') { - $old = get_component_name($old); - $new = get_component_name($new); + $old = $old_bug_obj->component; + $new = $new_bug_obj->component; $col = 'component'; } diff --git a/request.cgi b/request.cgi index 5563f32f7..5f90b87cb 100755 --- a/request.cgi +++ b/request.cgi @@ -19,6 +19,7 @@ # Rights Reserved. # # Contributor(s): Myk Melez <myk@mozilla.org> +# Frédéric Buclin <LpSolit@gmail.com> ################################################################################ # Script Initialization @@ -33,6 +34,8 @@ use Bugzilla; use Bugzilla::Flag; use Bugzilla::FlagType; use Bugzilla::User; +use Bugzilla::Product; +use Bugzilla::Component; # Make sure the user is logged in. my $user = Bugzilla->login(); @@ -174,23 +177,17 @@ sub queue { # Filter results by exact product or component. if (defined $cgi->param('product') && $cgi->param('product') ne "") { - my $product_id = get_product_id($cgi->param('product')); - if ($product_id) { - push(@criteria, "bugs.product_id = $product_id"); - push(@excluded_columns, 'product') unless $cgi->param('do_union'); - if (defined $cgi->param('component') && $cgi->param('component') ne "") { - my $component_id = get_component_id($product_id, $cgi->param('component')); - if ($component_id) { - push(@criteria, "bugs.component_id = $component_id"); - push(@excluded_columns, 'component') unless $cgi->param('do_union'); - } - else { ThrowUserError("component_not_valid", { 'product' => $cgi->param('product'), - 'name' => $cgi->param('component') }) } - } + my $product = Bugzilla::Product::check_product(scalar $cgi->param('product')); + push(@criteria, "bugs.product_id = " . $product->id); + push(@excluded_columns, 'product') unless $cgi->param('do_union'); + if (defined $cgi->param('component') && $cgi->param('component') ne "") { + my $component = + Bugzilla::Component::check_component($product, scalar $cgi->param('component')); + push(@criteria, "bugs.component_id = " . $component->id); + push(@excluded_columns, 'component') unless $cgi->param('do_union'); } - else { ThrowUserError("product_doesnt_exist", { 'product' => $cgi->param('product') }) } } - + # Filter results by flag types. my $form_type = $cgi->param('type'); if (defined $form_type && !grep($form_type eq $_, ("", "all"))) { diff --git a/template/en/default/global/code-error.html.tmpl b/template/en/default/global/code-error.html.tmpl index a71913540..a83629713 100644 --- a/template/en/default/global/code-error.html.tmpl +++ b/template/en/default/global/code-error.html.tmpl @@ -169,12 +169,7 @@ [% title = "Invalid Column Name" %] The custom sort order specified in your form submission contains an invalid column name <em>[% fragment FILTER html %]</em>. - - [% ELSIF error == "invalid_component" %] - [% title = "Invalid Component" %] - The [% name FILTER html %] component doesn't exist in the - [% product FILTER html %] product. - + [% ELSIF error == "invalid_dimensions" %] [% title = "Invalid Dimensions" %] The width or height specified is not a positive integer. @@ -228,11 +223,7 @@ for flag ID #[% id FILTER html %] [% END %] is invalid. - - [% ELSIF error == "flag_type_component_nonexistent" %] - The component <em>[% name FILTER html %]</em> does not exist - in the product <em>[% product FILTER html %]</em>. - + [% ELSIF error == "flag_type_component_without_product" %] A component was selected without a product being selected. @@ -246,10 +237,7 @@ [% ELSIF error == "flag_type_nonexistent" %] There is no flag type with the ID <em>[% id FILTER html %]</em>. - - [% ELSIF error == "flag_type_product_nonexistent" %] - The product <em>[% product FILTER html %]</em> does not exist. - + [% ELSIF error == "flag_type_target_type_invalid" %] The target type was neither <em>[% terms.bug %]</em> nor <em>attachment</em> but rather <em>[% target_type FILTER html %]</em>. |