diff options
Diffstat (limited to 'Bugzilla.pm')
-rw-r--r-- | Bugzilla.pm | 95 |
1 files changed, 86 insertions, 9 deletions
diff --git a/Bugzilla.pm b/Bugzilla.pm index c7f1a47cd..65ddcc2bc 100644 --- a/Bugzilla.pm +++ b/Bugzilla.pm @@ -76,6 +76,10 @@ use constant SHUTDOWNHTML_EXIT_SILENTLY => qw( whine.pl ); +# shutdownhtml pages are sent as an HTTP 503. After how many seconds +# should search engines attempt to index the page again? +use constant SHUTDOWNHTML_RETRY_AFTER => 3600; + ##################################################################### # Global Code ##################################################################### @@ -170,7 +174,12 @@ sub init_page { else { $extension = 'txt'; } - print Bugzilla->cgi->header() if i_am_cgi(); + if (i_am_cgi()) { + # Set the HTTP status to 503 when Bugzilla is down to avoid pages + # being indexed by search engines. + print Bugzilla->cgi->header(-status => 503, + -retry_after => SHUTDOWNHTML_RETRY_AFTER); + } my $t_output; $template->process("global/message.$extension.tmpl", $vars, \$t_output) || ThrowTemplateError($template->error); @@ -538,14 +547,52 @@ sub switch_to_main_db { return $class->dbh_main; } -sub get_fields { - my $class = shift; - my $criteria = shift; - # This function may be called during installation, and Field::match - # may fail at that time. so we want to return an empty list in that - # case. - my $fields = eval { Bugzilla::Field->match($criteria) } || []; - return @$fields; +sub fields { + my ($class, $criteria) = @_; + $criteria ||= {}; + my $cache = $class->request_cache; + + # We create an advanced cache for fields by type, so that we + # can avoid going back to the database for every fields() call. + # (And most of our fields() calls are for getting fields by type.) + # + # We also cache fields by name, because calling $field->name a few + # million times can be slow in calling code, but if we just do it + # once here, that makes things a lot faster for callers. + if (!defined $cache->{fields}) { + my @all_fields = Bugzilla::Field->get_all; + my (%by_name, %by_type); + foreach my $field (@all_fields) { + my $name = $field->name; + $by_type{$field->type}->{$name} = $field; + $by_name{$name} = $field; + } + $cache->{fields} = { by_type => \%by_type, by_name => \%by_name }; + } + + my $fields = $cache->{fields}; + my %requested; + if (my $types = delete $criteria->{type}) { + $types = ref($types) ? $types : [$types]; + %requested = map { %{ $fields->{by_type}->{$_} || {} } } @$types; + } + else { + %requested = %{ $fields->{by_name} }; + } + + my $do_by_name = delete $criteria->{by_name}; + + # Filtering before returning the fields based on + # the criterias. + foreach my $filter (keys %$criteria) { + foreach my $field (keys %requested) { + if ($requested{$field}->$filter != $criteria->{$filter}) { + delete $requested{$field}; + } + } + } + + return $do_by_name ? \%requested : [values %requested]; } sub active_custom_fields { @@ -607,6 +654,12 @@ sub _cleanup { $dbh->disconnect; } undef $_request_cache; + + # These are both set by CGI.pm but need to be undone so that + # Apache can actually shut down its children if it needs to. + foreach my $signal (qw(TERM PIPE)) { + $SIG{$signal} = 'DEFAULT' if $SIG{$signal} && $SIG{$signal} eq 'IGNORE'; + } } sub END { @@ -783,6 +836,30 @@ Essentially, causes calls to C<Bugzilla-E<gt>user> to return C<undef>. This has effect of logging out a user for the current request only; cookies and database sessions are left intact. +=item C<fields> + +This is the standard way to get arrays or hashes of L<Bugzilla::Field> +objects when you need them. It takes the following named arguments +in a hashref: + +=over + +=item C<by_name> + +If false (or not specified), this method will return an arrayref of +the requested fields. The order of the returned fields is random. + +If true, this method will return a hashref of fields, where the keys +are field names and the valules are L<Bugzilla::Field> objects. + +=item C<type> + +Either a single C<FIELD_TYPE_*> constant or an arrayref of them. If specified, +the returned fields will be limited to the types in the list. If you don't +specify this argument, all fields will be returned. + +=back + =item C<error_mode> Call either C<Bugzilla->error_mode(Bugzilla::Constants::ERROR_MODE_DIE)> |