diff options
-rw-r--r-- | Bugzilla/Bug.pm | 9 | ||||
-rw-r--r-- | Bugzilla/BugUrl/Bugzilla/Local.pm | 15 | ||||
-rw-r--r-- | Bugzilla/FlagType.pm | 22 | ||||
-rw-r--r-- | Bugzilla/Object.pm | 2 | ||||
-rw-r--r-- | Bugzilla/Product.pm | 4 | ||||
-rw-r--r-- | Bugzilla/WebService/Bug.pm | 4 | ||||
-rw-r--r-- | Bugzilla/WebService/Product.pm | 48 | ||||
-rw-r--r-- | docs/en/xml/installation.xml | 27 | ||||
-rw-r--r-- | extensions/Voting/Extension.pm | 23 | ||||
-rw-r--r-- | extensions/Voting/template/en/default/hook/admin/products/updated-changes.html.tmpl | 14 | ||||
-rw-r--r-- | template/en/default/admin/flag-type/edit.html.tmpl | 2 | ||||
-rw-r--r-- | template/en/default/admin/products/groupcontrol/updated.html.tmpl | 8 | ||||
-rw-r--r-- | template/en/default/search/search-specific.html.tmpl | 4 |
13 files changed, 134 insertions, 48 deletions
diff --git a/Bugzilla/Bug.pm b/Bugzilla/Bug.pm index 8beecdcd2..175bcd050 100644 --- a/Bugzilla/Bug.pm +++ b/Bugzilla/Bug.pm @@ -1130,9 +1130,7 @@ sub remove_from_db { # The bugs_fulltext table doesn't support transactions. $dbh->do("DELETE FROM bugs_fulltext WHERE bug_id = ?", undef, $bug_id); - # Now this bug no longer exists - $self->DESTROY; - return $self; + undef $self; } ##################################################################### @@ -2891,7 +2889,8 @@ sub remove_see_also { # Since we remove also the url from the referenced bug, # we need to notify changes for that bug too. $removed_bug_url = $removed_bug_url->[0]; - if ($removed_bug_url->isa('Bugzilla::BugUrl::Bugzilla::Local') + if ($removed_bug_url + and $removed_bug_url->isa('Bugzilla::BugUrl::Bugzilla::Local') and defined $removed_bug_url->ref_bug_url) { push @{ $self->{see_also_changes} }, @@ -3385,7 +3384,7 @@ sub reporter { sub see_also { my ($self) = @_; return [] if $self->{'error'}; - if (!defined $self->{see_also}) { + if (!exists $self->{see_also}) { my $ids = Bugzilla->dbh->selectcol_arrayref( 'SELECT id FROM bug_see_also WHERE bug_id = ?', undef, $self->id); diff --git a/Bugzilla/BugUrl/Bugzilla/Local.pm b/Bugzilla/BugUrl/Bugzilla/Local.pm index 233acbe66..bdfae2835 100644 --- a/Bugzilla/BugUrl/Bugzilla/Local.pm +++ b/Bugzilla/BugUrl/Bugzilla/Local.pm @@ -95,13 +95,20 @@ sub remove_from_db { sub should_handle { my ($class, $uri) = @_; - return $uri->as_string =~ m/^\w+$/ ? 1 : 0; + # Check if it is either a bug id number or an alias. + return 1 if $uri->as_string =~ m/^\w+$/; + # Check if it is a local Bugzilla uri and call + # Bugzilla::BugUrl::Bugzilla to check if it's a valid Bugzilla + # see also url. my $canonical_local = URI->new($class->local_uri)->canonical; + if ($canonical_local->authority eq $uri->canonical->authority + and $canonical_local->path eq $uri->canonical->path) + { + return $class->SUPER::should_handle($uri); + } - # Treating the domain case-insensitively and ignoring http(s):// - return ($canonical_local->authority eq $uri->canonical->authority - and $canonical_local->path eq $uri->canonical->path) ? 1 : 0; + return 0; } sub _check_value { diff --git a/Bugzilla/FlagType.pm b/Bugzilla/FlagType.pm index bd3f7b054..ea81dfe46 100644 --- a/Bugzilla/FlagType.pm +++ b/Bugzilla/FlagType.pm @@ -118,6 +118,8 @@ sub create { $class->check_required_create_fields(@_); my $params = $class->run_create_validators(@_); + # In the DB, only the first character of the target type is stored. + $params->{target_type} = substr($params->{target_type}, 0, 1); # Extract everything which is not a valid column name. $params->{grant_group_id} = delete $params->{grant_group}; @@ -357,7 +359,15 @@ sub set_request_group { $_[0]->set('request_group_id', $_[1]); } sub set_clusions { my ($self, $list) = @_; + my $user = Bugzilla->user; my %products; + my $params = {}; + + # If the user has editcomponents privs, then we only need to make sure + # that the product exists. + if ($user->in_group('editcomponents')) { + $params->{allow_inaccessible} = 1; + } foreach my $category (keys %$list) { my %clusions; @@ -369,8 +379,16 @@ sub set_clusions { my $comp_name = '__Any__'; # Does the product exist? if ($prod_id) { - $products{$prod_id} ||= Bugzilla::Product->check({ id => $prod_id }); - detaint_natural($prod_id); + detaint_natural($prod_id) + || ThrowCodeError('param_must_be_numeric', + { function => 'Bugzilla::FlagType::set_clusions' }); + + if (!$products{$prod_id}) { + $params->{id} = $prod_id; + $products{$prod_id} = Bugzilla::Product->check($params); + $user->in_group('editcomponents', $prod_id) + || ThrowUserError('product_access_denied', $params); + } $prod_name = $products{$prod_id}->name; # Does the component belong to this product? diff --git a/Bugzilla/Object.pm b/Bugzilla/Object.pm index 1cad3e829..29a6415b9 100644 --- a/Bugzilla/Object.pm +++ b/Bugzilla/Object.pm @@ -441,6 +441,8 @@ sub audit_log { # During update, it's the actual %changes hash produced by update(). foreach my $field (keys %$changes) { + # Skip private changes. + next if $field =~ /^_/; my ($from, $to) = @{ $changes->{$field} }; $sth->execute($user_id, $class, $self->id, $field, $from, $to); } diff --git a/Bugzilla/Product.pm b/Bugzilla/Product.pm index 85524ac47..a0079a033 100644 --- a/Bugzilla/Product.pm +++ b/Bugzilla/Product.pm @@ -223,7 +223,7 @@ sub update { $new_setting->{group}->name, Bugzilla->user->id, $timestamp); } - push(@{$changes->{'group_controls'}->{'now_mandatory'}}, + push(@{$changes->{'_group_controls'}->{'now_mandatory'}}, {name => $new_setting->{group}->name, bug_count => scalar @$bug_ids}); } @@ -248,7 +248,7 @@ sub update { $old_setting->{group}->name, '', Bugzilla->user->id, $timestamp); } - push(@{$changes->{'group_controls'}->{'now_na'}}, + push(@{$changes->{'_group_controls'}->{'now_na'}}, {name => $old_setting->{group}->name, bug_count => scalar @$bug_ids}); } diff --git a/Bugzilla/WebService/Bug.pm b/Bugzilla/WebService/Bug.pm index da2393033..fb2b7b65d 100644 --- a/Bugzilla/WebService/Bug.pm +++ b/Bugzilla/WebService/Bug.pm @@ -204,7 +204,7 @@ sub _legal_field_values { name => $self->type('string', $status->name), is_open => $self->type('boolean', $status->is_open), sort_key => $self->type('int', $status->sortkey), - sortkey => $self->type('int', $status->sortkey), # depricated + sortkey => $self->type('int', $status->sortkey), # deprecated can_change_to => \@can_change_to, visibility_values => [], }); @@ -218,7 +218,7 @@ sub _legal_field_values { push(@result, { name => $self->type('string', $value->name), sort_key => $self->type('int' , $value->sortkey), - sortkey => $self->type('int' , $value->sortkey), # depricated + sortkey => $self->type('int' , $value->sortkey), # deprecated visibility_values => [ defined $vis_val ? $self->type('string', $vis_val->name) : () diff --git a/Bugzilla/WebService/Product.pm b/Bugzilla/WebService/Product.pm index 9aeb8597a..842657575 100644 --- a/Bugzilla/WebService/Product.pm +++ b/Bugzilla/WebService/Product.pm @@ -122,11 +122,13 @@ sub _product_to_hash { my ($self, $params, $product) = @_; my $field_data = { - internals => $product, id => $self->type('int', $product->id), name => $self->type('string', $product->name), description => $self->type('string', $product->description), is_active => $self->type('boolean', $product->is_active), + default_milestone => $self->type('string', $product->default_milestone), + has_unconfirmed => $self->type('boolean', $product->allows_unconfirmed), + classification => $self->_classification_to_hash($product->classification), }; if (filter_wants($params, 'components')) { $field_data->{components} = [map { @@ -146,6 +148,20 @@ sub _product_to_hash { return filter($params, $field_data); } +sub _classification_to_hash { + my ($self, $classification) = @_; + return { + id => + $self->type('int', $classification->id), + name => + $self->type('string', $classification->name), + description => + $self->type('string' , $classification->description), + sort_key => + $self->type('int', $classification->sortkey), + }; +} + sub _component_to_hash { my ($self, $component) = @_; return { @@ -318,7 +334,7 @@ hashes. Each hash describes a product, and has the following items: =item C<id> -C<int> An integer id uniquely idenfifying the product in this installation only. +C<int> An integer id uniquely identifying the product in this installation only. =item C<name> @@ -333,6 +349,20 @@ C<string> A description of the product, which may contain HTML. C<boolean> A boolean indicating if the product is active. +=item C<default_milestone> + +C<string> The name of the default milestone for the product. + +=item C<has_unconfirmed> + +C<boolean> Indicates whether the UNCONFIRMED bug status is available +for this product. + +=item C<classification> + +C<hash> Contains the classification C<id>, C<name>, C<description> +and C<sort_key> as keys. + =item C<components> C<array> An array of hashes, where each hash describes a component, and has the @@ -342,7 +372,7 @@ following items: =item C<id> -C<int> An integer id uniquely idenfifying the component in this installation +C<int> An integer id uniquely identifying the component in this installation only. =item C<name> @@ -386,12 +416,6 @@ following items: C<name>, C<sort_key> and C<is_active>. C<array> An array of hashes, where each hash describes a milestone, and has the following items: C<name>, C<sort_key> and C<is_active>. -=item C<internals> - -B<UNSTABLE> - -An internal representation of the product. - =back Note, that if the user tries to access a product that is not in the @@ -407,8 +431,10 @@ is returned. =item In Bugzilla B<4.2>, C<names> was added as an input parameter. -=item In Bugzilla B<4.2> C<components>, C<versions>, and C<milestones> -were added to the fields returned by C<get>. +=item In Bugzilla B<4.2>, C<classification>, C<components>, C<versions>, +C<milestones>, C<default_milestone> and C<has_unconfirmed> were added to +the fields returned by C<get> as a replacement for C<internals>, which has +been removed. =back diff --git a/docs/en/xml/installation.xml b/docs/en/xml/installation.xml index 8349ef012..8df457439 100644 --- a/docs/en/xml/installation.xml +++ b/docs/en/xml/installation.xml @@ -618,7 +618,7 @@ the user you will create for your database. Pick a strong password (for simplicity, it should not contain single quote characters) and put it here. $db_driver can be either 'mysql', - 'Pg' or 'oracle'. + 'Pg', 'Oracle' or 'Sqlite'. </para> <note> @@ -662,8 +662,8 @@ <para> This section deals with configuring your database server for use with Bugzilla. Currently, MySQL (<xref linkend="mysql"/>), - PostgreSQL (<xref linkend="postgresql"/>) and Oracle (<xref linkend="oracle"/>) - are available. + PostgreSQL (<xref linkend="postgresql"/>), Oracle (<xref linkend="oracle"/>) + and SQLite (<xref linkend="sqlite"/>) are available. </para> <section id="database-schema"> @@ -946,7 +946,26 @@ max_allowed_packet=4M </para> </section> </section> - </section> + + <section id="sqlite"> + <title>SQLite</title> + + <caution> + <para> + Due to SQLite's <ulink url="http://sqlite.org/faq.html#q5">concurrency + limitations</ulink> we recommend SQLite only for small and development + Bugzilla installations. + </para> + </caution> + + <para> + No special configuration is required to run Bugzilla on SQLite. + The database will be stored in <filename>data/db/$db_name</filename>, + where <literal>$db_name</literal> is the database name defined + in <filename>localconfig</filename>. + </para> + </section> + </section> <section> <title>checksetup.pl</title> diff --git a/extensions/Voting/Extension.pm b/extensions/Voting/Extension.pm index 8a786e659..6a90176ec 100644 --- a/extensions/Voting/Extension.pm +++ b/extensions/Voting/Extension.pm @@ -52,6 +52,21 @@ use constant REL_VOTER => 4; # Installation # ################ +BEGIN { + *Bugzilla::Bug::votes = \&votes; +} + +sub votes { + my $self = shift; + my $dbh = Bugzilla->dbh; + + return $self->{votes} if exists $self->{votes}; + + $self->{votes} = $dbh->selectrow_array('SELECT votes FROM bugs WHERE bug_id = ?', + undef, $self->id); + return $self->{votes}; +} + sub db_schema_abstract_schema { my ($self, $args) = @_; $args->{'schema'}->{'votes'} = { @@ -663,7 +678,7 @@ sub _modify_bug_votes { } } - $changes->{'too_many_votes'} = \@toomanyvotes_list; + $changes->{'_too_many_votes'} = \@toomanyvotes_list; # 2. too many total votes for a single user. # This part doesn't work in the general case because _remove_votes @@ -710,7 +725,7 @@ sub _modify_bug_votes { } } - $changes->{'too_many_total_votes'} = \@toomanytotalvotes_list; + $changes->{'_too_many_total_votes'} = \@toomanytotalvotes_list; # 3. enough votes to confirm my $bug_list = $dbh->selectcol_arrayref( @@ -723,7 +738,7 @@ sub _modify_bug_votes { my $confirmed = _confirm_if_vote_confirmed($bug_id); push (@updated_bugs, $bug_id) if $confirmed; } - $changes->{'confirmed_bugs'} = \@updated_bugs; + $changes->{'_confirmed_bugs'} = \@updated_bugs; # Now that changes are done, we can send emails to voters. foreach my $msg (@msgs) { @@ -733,7 +748,7 @@ sub _modify_bug_votes { foreach my $bug_id (@updated_bugs) { my $sent_bugmail = Bugzilla::BugMail::Send( $bug_id, { changer => Bugzilla->user }); - $changes->{'confirmed_bugs_sent_bugmail'}->{$bug_id} = $sent_bugmail; + $changes->{'_confirmed_bugs_sent_bugmail'}->{$bug_id} = $sent_bugmail; } } diff --git a/extensions/Voting/template/en/default/hook/admin/products/updated-changes.html.tmpl b/extensions/Voting/template/en/default/hook/admin/products/updated-changes.html.tmpl index af2b1c102..15fb1efe0 100644 --- a/extensions/Voting/template/en/default/hook/admin/products/updated-changes.html.tmpl +++ b/extensions/Voting/template/en/default/hook/admin/products/updated-changes.html.tmpl @@ -56,8 +56,8 @@ <p>Checking existing votes in this product for anybody who now has too many votes for [% terms.abug %]...<br> - [% IF changes.too_many_votes.size %] - [% FOREACH detail = changes.too_many_votes %] + [% IF changes._too_many_votes.size %] + [% FOREACH detail = changes._too_many_votes %] →removed votes for [% terms.bug %] <a href="show_bug.cgi?id= [%- detail.id FILTER uri %]"> [%- detail.id FILTER html %]</a> from [% detail.name FILTER html %]<br> @@ -69,8 +69,8 @@ <p>Checking existing votes in this product for anybody who now has too many total votes...<br> - [% IF changes.too_many_total_votes.size %] - [% FOREACH detail = changes.too_many_total_votes %] + [% IF changes._too_many_total_votes.size %] + [% FOREACH detail = changes._too_many_total_votes %] →removed votes for [% terms.bug %] <a href="show_bug.cgi?id= [%- detail.id FILTER uri %]"> [%- detail.id FILTER html %]</a> from [% detail.name FILTER html %]<br> @@ -82,15 +82,15 @@ <p>Checking unconfirmed [% terms.bugs %] in this product for any which now have sufficient votes...<br> - [% IF changes.confirmed_bugs.size %] - [% FOREACH id = changes.confirmed_bugs %] + [% IF changes._confirmed_bugs.size %] + [% FOREACH id = changes._confirmed_bugs %] [%# This is INCLUDED instead of PROCESSED to avoid variables getting overwritten, which happens otherwise %] [% INCLUDE bug/process/results.html.tmpl type = 'votes' header_done = 1 - sent_bugmail = changes.confirmed_bugs_sent_bugmail.$id + sent_bugmail = changes._confirmed_bugs_sent_bugmail.$id id = id %] [% END %] diff --git a/template/en/default/admin/flag-type/edit.html.tmpl b/template/en/default/admin/flag-type/edit.html.tmpl index f44c44d9d..2cb985a47 100644 --- a/template/en/default/admin/flag-type/edit.html.tmpl +++ b/template/en/default/admin/flag-type/edit.html.tmpl @@ -262,7 +262,7 @@ [%- group.name FILTER html ~%] </option> [% END %] - [% IF !group_found && type.${selname} %] + [% IF !group_found && type.${selname}.name %] <option value="[% type.${selname}.name FILTER html %]" selected="selected"> [%- type.${selname}.name FILTER html ~%] </option> diff --git a/template/en/default/admin/products/groupcontrol/updated.html.tmpl b/template/en/default/admin/products/groupcontrol/updated.html.tmpl index 2f59cae68..353ce5c75 100644 --- a/template/en/default/admin/products/groupcontrol/updated.html.tmpl +++ b/template/en/default/admin/products/groupcontrol/updated.html.tmpl @@ -27,16 +27,16 @@ title = title %] <p> -[% IF changes.group_controls.now_na.size %] - [% FOREACH g = changes.group_controls.now_na %] +[% IF changes._group_controls.now_na.size %] + [% FOREACH g = changes._group_controls.now_na %] Removing [% terms.bugs %] from group '[% g.name FILTER html %]' which no longer applies to this product<p> [% g.bug_count FILTER html %] [%+ terms.bugs %] removed<p> [% END %] [% END %] -[% IF changes.group_controls.now_mandatory.size %] - [% FOREACH g = changes.group_controls.now_mandatory %] +[% IF changes._group_controls.now_mandatory.size %] + [% FOREACH g = changes._group_controls.now_mandatory %] Adding [% terms.bugs %] to group '[% g.name FILTER html %]' which is mandatory for this product<p> [% g.bug_count FILTER html %] [%+ terms.bugs %] added<p> diff --git a/template/en/default/search/search-specific.html.tmpl b/template/en/default/search/search-specific.html.tmpl index 1d7229cf7..31d950ec5 100644 --- a/template/en/default/search/search-specific.html.tmpl +++ b/template/en/default/search/search-specific.html.tmpl @@ -46,7 +46,7 @@ for "crash secure SSL flash". <table summary="Search fields" class="bz_simple_search_form"> <tr> <th> - <label for="bug_status">Status:</label> + <label for="bug_status">[% field_descs.bug_status FILTER html %]:</label> </th> <td> <select name="bug_status" id="bug_status"> @@ -64,7 +64,7 @@ for "crash secure SSL flash". </tr> <tr> <th> - <label for="product">Product:</label> + <label for="product">[% field_descs.product FILTER html %]:</label> </th> <td> <select name="product" id="product"> |