diff options
author | Christian Ruppert <idl0r@gentoo.org> | 2015-07-11 15:27:33 +0200 |
---|---|---|
committer | Christian Ruppert <idl0r@gentoo.org> | 2015-07-11 15:27:33 +0200 |
commit | 4b2ce2725e9a4525e273fb1b08243aad74770a3d (patch) | |
tree | c90fb0fef5c9ac923817f908f1c3586efa47ec59 /Bugzilla.pm | |
parent | Bumped version to 4.4.9 (diff) | |
download | bugzilla-4b2ce2725e9a4525e273fb1b08243aad74770a3d.tar.gz bugzilla-4b2ce2725e9a4525e273fb1b08243aad74770a3d.tar.bz2 bugzilla-4b2ce2725e9a4525e273fb1b08243aad74770a3d.zip |
Vanilla 4.4.9 to 5.0 without history due to massive merge conflicts
Diffstat (limited to 'Bugzilla.pm')
-rw-r--r-- | Bugzilla.pm | 233 |
1 files changed, 162 insertions, 71 deletions
diff --git a/Bugzilla.pm b/Bugzilla.pm index 6e31ba71a..e3184fdb8 100644 --- a/Bugzilla.pm +++ b/Bugzilla.pm @@ -7,7 +7,9 @@ package Bugzilla; +use 5.10.1; use strict; +use warnings; # We want any compile errors to get to the browser, if possible. BEGIN { @@ -18,23 +20,24 @@ BEGIN { } } -use Bugzilla::Config; -use Bugzilla::Constants; use Bugzilla::Auth; use Bugzilla::Auth::Persist::Cookie; use Bugzilla::CGI; -use Bugzilla::Extension; +use Bugzilla::Config; +use Bugzilla::Constants; use Bugzilla::DB; +use Bugzilla::Error; +use Bugzilla::Extension; +use Bugzilla::Field; +use Bugzilla::Flag; use Bugzilla::Install::Localconfig qw(read_localconfig); -use Bugzilla::Install::Requirements qw(OPTIONAL_MODULES); +use Bugzilla::Install::Requirements qw(OPTIONAL_MODULES have_vers); use Bugzilla::Install::Util qw(init_console include_languages); +use Bugzilla::Memcached; use Bugzilla::Template; +use Bugzilla::Token; use Bugzilla::User; -use Bugzilla::Error; use Bugzilla::Util; -use Bugzilla::Field; -use Bugzilla::Flag; -use Bugzilla::Token; use File::Basename; use File::Spec::Functions; @@ -119,8 +122,8 @@ sub init_page { # # This code must go here. It cannot go anywhere in Bugzilla::CGI, because # it uses Template, and that causes various dependency loops. - if (Bugzilla->params->{"shutdownhtml"} - && !grep { $_ eq $script } SHUTDOWNHTML_EXEMPT) + if (!grep { $_ eq $script } SHUTDOWNHTML_EXEMPT + and Bugzilla->params->{'shutdownhtml'}) { # Allow non-cgi scripts to exit silently (without displaying any # message), if desired. At this point, no DBI call has been made @@ -163,10 +166,8 @@ sub init_page { print Bugzilla->cgi->header(-status => 503, -retry_after => SHUTDOWNHTML_RETRY_AFTER); } - my $t_output; - $template->process("global/message.$extension.tmpl", $vars, \$t_output) + $template->process("global/message.$extension.tmpl", $vars) || ThrowTemplateError($template->error); - print $t_output . "\n"; exit; } } @@ -176,9 +177,7 @@ sub init_page { ##################################################################### sub template { - my $class = shift; - $class->request_cache->{template} ||= Bugzilla::Template->create(); - return $class->request_cache->{template}; + return $_[0]->request_cache->{template} ||= Bugzilla::Template->create(); } sub template_inner { @@ -186,9 +185,7 @@ sub template_inner { my $cache = $class->request_cache; my $current_lang = $cache->{template_current_lang}->[0]; $lang ||= $current_lang || ''; - $class->request_cache->{"template_inner_$lang"} - ||= Bugzilla::Template->create(language => $lang); - return $class->request_cache->{"template_inner_$lang"}; + return $cache->{"template_inner_$lang"} ||= Bugzilla::Template->create(language => $lang); } our $extension_packages; @@ -223,7 +220,7 @@ sub feature { foreach my $package (@{ OPTIONAL_MODULES() }) { foreach my $f (@{ $package->{feature} }) { $feature_map->{$f} ||= []; - push(@{ $feature_map->{$f} }, $package->{module}); + push(@{ $feature_map->{$f} }, $package); } } $cache->{feature_map} = $feature_map; @@ -234,22 +231,15 @@ sub feature { } my $success = 1; - foreach my $module (@{ $feature_map->{$feature} }) { - # We can't use a string eval and "use" here (it kills Template-Toolkit, - # see https://rt.cpan.org/Public/Bug/Display.html?id=47929), so we have - # to do a block eval. - $module =~ s{::}{/}g; - $module .= ".pm"; - eval { require $module; 1; } or $success = 0; + foreach my $package (@{ $feature_map->{$feature} }) { + have_vers($package) or $success = 0; } $cache->{feature}->{$feature} = $success; return $success; } sub cgi { - my $class = shift; - $class->request_cache->{cgi} ||= new Bugzilla::CGI(); - return $class->request_cache->{cgi}; + return $_[0]->request_cache->{cgi} ||= new Bugzilla::CGI(); } sub input_params { @@ -273,15 +263,11 @@ sub localconfig { } sub params { - my $class = shift; - $class->request_cache->{params} ||= Bugzilla::Config::read_param_file(); - return $class->request_cache->{params}; + return $_[0]->request_cache->{params} ||= Bugzilla::Config::read_param_file(); } sub user { - my $class = shift; - $class->request_cache->{user} ||= new Bugzilla::User; - return $class->request_cache->{user}; + return $_[0]->request_cache->{user} ||= new Bugzilla::User; } sub set_user { @@ -290,8 +276,7 @@ sub set_user { } sub sudoer { - my $class = shift; - return $class->request_cache->{sudoer}; + return $_[0]->request_cache->{sudoer}; } sub sudo_request { @@ -413,28 +398,20 @@ sub logout_request { } sub job_queue { - my $class = shift; require Bugzilla::JobQueue; - $class->request_cache->{job_queue} ||= Bugzilla::JobQueue->new(); - return $class->request_cache->{job_queue}; + return $_[0]->request_cache->{job_queue} ||= Bugzilla::JobQueue->new(); } sub dbh { - my $class = shift; # If we're not connected, then we must want the main db - $class->request_cache->{dbh} ||= $class->dbh_main; - - return $class->request_cache->{dbh}; + return $_[0]->request_cache->{dbh} ||= $_[0]->dbh_main; } sub dbh_main { - my $class = shift; - $class->request_cache->{dbh_main} ||= Bugzilla::DB::connect_main(); - return $class->request_cache->{dbh_main}; + return $_[0]->request_cache->{dbh_main} ||= Bugzilla::DB::connect_main(); } sub languages { - my $class = shift; return Bugzilla::Install::Util::supported_languages(); } @@ -487,6 +464,9 @@ sub usage_mode { elsif ($newval == USAGE_MODE_TEST) { $class->error_mode(ERROR_MODE_TEST); } + elsif ($newval == USAGE_MODE_REST) { + $class->error_mode(ERROR_MODE_REST); + } else { ThrowCodeError('usage_mode_invalid', {'invalid_usage_mode', $newval}); @@ -550,6 +530,11 @@ sub switch_to_main_db { return $class->dbh_main; } +sub is_shadow_db { + my $class = shift; + return $class->request_cache->{dbh} != $class->dbh_main; +} + sub fields { my ($class, $criteria) = @_; $criteria ||= {}; @@ -618,13 +603,8 @@ sub has_flags { } sub local_timezone { - my $class = shift; - - if (!defined $class->process_cache->{local_timezone}) { - $class->process_cache->{local_timezone} = - DateTime::TimeZone->new(name => 'local'); - } - return $class->process_cache->{local_timezone}; + return $_[0]->process_cache->{local_timezone} + ||= DateTime::TimeZone->new(name => 'local'); } # This creates the request cache for non-mod_perl installations. @@ -666,18 +646,27 @@ sub process_cache { return $_process_cache; } +# This is a memcached wrapper, which provides cross-process and cross-system +# caching. +sub memcached { + return $_[0]->process_cache->{memcached} ||= Bugzilla::Memcached->_new(); +} + # Private methods # Per-process cleanup. Note that this is a plain subroutine, not a method, # so we don't have $class available. sub _cleanup { - my $main = Bugzilla->request_cache->{dbh_main}; - my $shadow = Bugzilla->request_cache->{dbh_shadow}; + my $cache = Bugzilla->request_cache; + my $main = $cache->{dbh_main}; + my $shadow = $cache->{dbh_shadow}; foreach my $dbh ($main, $shadow) { next if !$dbh; $dbh->bz_rollback_transaction() if $dbh->bz_in_transaction; $dbh->disconnect; } + my $smtp = $cache->{smtp}; + $smtp->disconnect if $smtp; clear_request_cache(); # These are both set by CGI.pm but need to be undone so that @@ -769,7 +758,7 @@ If you ever need a L<Bugzilla::Template> object while you're already processing a template, use this. Also use it if you want to specify the language to use. If no argument is passed, it uses the last language set. If the argument is "" (empty string), the language is -reset to the current one (the one used by Bugzilla->template). +reset to the current one (the one used by C<Bugzilla-E<gt>template>). =item C<cgi> @@ -846,7 +835,7 @@ default), LOGOUT_ALL or LOGOUT_KEEP_CURRENT. =item C<logout_user($user)> -Logs out the specified user (invalidating all his sessions), taking a +Logs out the specified user (invalidating all their sessions), taking a Bugzilla::User instance. =item C<logout_by_id($id)> @@ -887,8 +876,8 @@ specify this argument, all fields will be returned. =item C<error_mode> -Call either C<Bugzilla->error_mode(Bugzilla::Constants::ERROR_MODE_DIE)> -or C<Bugzilla->error_mode(Bugzilla::Constants::ERROR_MODE_DIE_SOAP_FAULT)> to +Call either C<Bugzilla-E<gt>error_mode(Bugzilla::Constants::ERROR_MODE_DIE)> +or C<Bugzilla-E<gt>error_mode(Bugzilla::Constants::ERROR_MODE_DIE_SOAP_FAULT)> to change this flag's default of C<Bugzilla::Constants::ERROR_MODE_WEBPAGE> and to indicate that errors should be passed to error mode specific error handlers rather than being sent to a browser and finished with an exit(). @@ -897,24 +886,24 @@ This is useful, for example, to keep C<eval> blocks from producing wild HTML on errors, making it easier for you to catch them. (Remember to reset the error mode to its previous value afterwards, though.) -C<Bugzilla->error_mode> will return the current state of this flag. +C<Bugzilla-E<gt>error_mode> will return the current state of this flag. -Note that C<Bugzilla->error_mode> is being called by C<Bugzilla->usage_mode> on +Note that C<Bugzilla-E<gt>error_mode> is being called by C<Bugzilla-E<gt>usage_mode> on usage mode changes. =item C<usage_mode> -Call either C<Bugzilla->usage_mode(Bugzilla::Constants::USAGE_MODE_CMDLINE)> -or C<Bugzilla->usage_mode(Bugzilla::Constants::USAGE_MODE_XMLRPC)> near the +Call either C<Bugzilla-E<gt>usage_mode(Bugzilla::Constants::USAGE_MODE_CMDLINE)> +or C<Bugzilla-E<gt>usage_mode(Bugzilla::Constants::USAGE_MODE_XMLRPC)> near the beginning of your script to change this flag's default of C<Bugzilla::Constants::USAGE_MODE_BROWSER> and to indicate that Bugzilla is being called in a non-interactive manner. This influences error handling because on usage mode changes, C<usage_mode> -calls C<Bugzilla->error_mode> to set an error mode which makes sense for the +calls C<Bugzilla-E<gt>error_mode> to set an error mode which makes sense for the usage mode. -C<Bugzilla->usage_mode> will return the current state of this flag. +C<Bugzilla-E<gt>usage_mode> will return the current state of this flag. =item C<installation_mode> @@ -951,11 +940,17 @@ Switch from using the main database to using the shadow database. Change the database object to refer to the main database. +=item C<is_shadow_db> + +Returns true if the currently active database is the shadow database. +Returns false if a the currently active database is the man database, or if a +shadow database is not configured or enabled. + =item C<params> -The current Parameters of Bugzilla, as a hashref. If C<data/params> -does not exist, then we return an empty hashref. If C<data/params> -is unreadable or is not valid perl, we C<die>. +The current Parameters of Bugzilla, as a hashref. If C<data/params.json> +does not exist, then we return an empty hashref. If C<data/params.json> +is unreadable or is not valid, we C<die>. =item C<local_timezone> @@ -975,3 +970,99 @@ Tells you whether or not a specific feature is enabled. For names of features, see C<OPTIONAL_MODULES> in C<Bugzilla::Install::Requirements>. =back + +=head1 B<CACHING> + +Bugzilla has several different caches available which provide different +capabilities and lifetimes. + +The keys of all caches are unregulated; use of prefixes is suggested to avoid +collisions. + +=over + +=item B<Request Cache> + +The request cache is a hashref which supports caching any perl variable for the +duration of the current request. At the end of the current request the contents +of this cache are cleared. + +Examples of its use include caching objects to avoid re-fetching the same data +from the database, and passing data between otherwise unconnected parts of +Bugzilla. + +=over + +=item C<request_cache> + +Returns a hashref which can be checked and modified to store any perl variable +for the duration of the current request. + +=item C<clear_request_cache> + +Removes all entries from the C<request_cache>. + +=back + +=item B<Process Cache> + +The process cache is a hashref which support caching of any perl variable. If +Bugzilla is configured to run using Apache mod_perl, the contents of this cache +are persisted across requests for the lifetime of the Apache worker process +(which varies depending on the SizeLimit configuration in mod_perl.pl). + +If Bugzilla isn't running under mod_perl, the process cache's contents are +cleared at the end of the request. + +The process cache is only suitable for items which never change while Bugzilla +is running (for example the path where Bugzilla is installed). + +=over + +=item C<process_cache> + +Returns a hashref which can be checked and modified to store any perl variable +for the duration of the current process (mod_perl) or request (mod_cgi). + +=back + +=item B<Memcached> + +If Memcached is installed and configured, Bugzilla can use it to cache data +across requests and between webheads. Unlike the request and process caches, +only scalars, hashrefs, and arrayrefs can be stored in Memcached. + +Memcached integration is only required for large installations of Bugzilla -- if +you have multiple webheads then configuring Memcached is recommended. + +=over + +=item C<memcached> + +Returns a C<Bugzilla::Memcached> object. An object is always returned even if +Memcached is not available. + +See the documentation for the C<Bugzilla::Memcached> module for more +information. + +=back + +=back + +=head1 B<Methods in need of POD> + +=over + +=item init_page + +=item extensions + +=item logout_user_by_id + +=item localconfig + +=item active_custom_fields + +=item has_flags + +=back |