~ubuntu-branches/debian/squeeze/bugzilla/squeeze

« back to all changes in this revision

Viewing changes to Bugzilla.pm

  • Committer: Bazaar Package Importer
  • Author(s): Raphael Bossek
  • Date: 2008-06-27 22:34:34 UTC
  • mfrom: (1.1.7 upstream)
  • Revision ID: james.westby@ubuntu.com-20080627223434-0ib57vstn43bb4a3
Tags: 3.0.4.1-1
* Update of French, Russian and German translations. (closes: #488251)
* Added Bulgarian and Belarusian translations.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# -*- Mode: perl; indent-tabs-mode: nil -*-
2
 
#
3
 
# The contents of this file are subject to the Mozilla Public
4
 
# License Version 1.1 (the "License"); you may not use this file
5
 
# except in compliance with the License. You may obtain a copy of
6
 
# the License at http://www.mozilla.org/MPL/
7
 
#
8
 
# Software distributed under the License is distributed on an "AS
9
 
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
10
 
# implied. See the License for the specific language governing
11
 
# rights and limitations under the License.
12
 
#
13
 
# The Original Code is the Bugzilla Bug Tracking System.
14
 
#
15
 
# The Initial Developer of the Original Code is Netscape Communications
16
 
# Corporation. Portions created by Netscape are
17
 
# Copyright (C) 1998 Netscape Communications Corporation. All
18
 
# Rights Reserved.
19
 
#
20
 
# Contributor(s): Bradley Baetz <bbaetz@student.usyd.edu.au>
21
 
#                 Erik Stambaugh <erik@dasbistro.com>
22
 
#                 A. Karl Kornel <karl@kornel.name>
23
 
#                 Marc Schumann <wurblzap@gmail.com>
24
 
 
25
 
package Bugzilla;
26
 
 
27
 
use strict;
28
 
 
29
 
use Bugzilla::Config;
30
 
use Bugzilla::Constants;
31
 
use Bugzilla::Auth;
32
 
use Bugzilla::Auth::Persist::Cookie;
33
 
use Bugzilla::CGI;
34
 
use Bugzilla::DB;
35
 
use Bugzilla::Install::Localconfig qw(read_localconfig);
36
 
use Bugzilla::Template;
37
 
use Bugzilla::User;
38
 
use Bugzilla::Error;
39
 
use Bugzilla::Util;
40
 
use Bugzilla::Field;
41
 
 
42
 
use File::Basename;
43
 
use Safe;
44
 
 
45
 
# This creates the request cache for non-mod_perl installations.
46
 
our $_request_cache = {};
47
 
 
48
 
#####################################################################
49
 
# Constants
50
 
#####################################################################
51
 
 
52
 
# Scripts that are not stopped by shutdownhtml being in effect.
53
 
use constant SHUTDOWNHTML_EXEMPT => [
54
 
    'editparams.cgi',
55
 
    'checksetup.pl',
56
 
    'recode.pl',
57
 
];
58
 
 
59
 
# Non-cgi scripts that should silently exit.
60
 
use constant SHUTDOWNHTML_EXIT_SILENTLY => [
61
 
    'whine.pl'
62
 
];
63
 
 
64
 
#####################################################################
65
 
# Global Code
66
 
#####################################################################
67
 
 
68
 
# The following subroutine is for debugging purposes only.
69
 
# Uncommenting this sub and the $::SIG{__DIE__} trap underneath it will
70
 
# cause any fatal errors to result in a call stack trace to help track
71
 
# down weird errors.
72
 
#
73
 
#sub die_with_dignity {
74
 
#    use Carp ();
75
 
#    my ($err_msg) = @_;
76
 
#    print $err_msg;
77
 
#    Carp::confess($err_msg);
78
 
#}
79
 
#$::SIG{__DIE__} = \&Bugzilla::die_with_dignity;
80
 
 
81
 
sub init_page {
82
 
 
83
 
    # Some environment variables are not taint safe
84
 
    delete @::ENV{'PATH', 'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};
85
 
    # Some modules throw undefined errors (notably File::Spec::Win32) if
86
 
    # PATH is undefined.
87
 
    $ENV{'PATH'} = '';
88
 
 
89
 
    # IIS prints out warnings to the webpage, so ignore them, or log them
90
 
    # to a file if the file exists.
91
 
    if ($ENV{SERVER_SOFTWARE} && $ENV{SERVER_SOFTWARE} =~ /microsoft-iis/i) {
92
 
        $SIG{__WARN__} = sub {
93
 
            my ($msg) = @_;
94
 
            my $datadir = bz_locations()->{'datadir'};
95
 
            if (-w "$datadir/errorlog") {
96
 
                my $warning_log = new IO::File(">>$datadir/errorlog");
97
 
                print $warning_log $msg;
98
 
                $warning_log->close();
99
 
            }
100
 
        };
101
 
    }
102
 
 
103
 
    # If Bugzilla is shut down, do not allow anything to run, just display a
104
 
    # message to the user about the downtime and log out.  Scripts listed in 
105
 
    # SHUTDOWNHTML_EXEMPT are exempt from this message.
106
 
    #
107
 
    # Because this is code which is run live from perl "use" commands of other
108
 
    # scripts, we're skipping this part if we get here during a perl syntax 
109
 
    # check -- runtests.pl compiles scripts without running them, so we 
110
 
    # need to make sure that this check doesn't apply to 'perl -c' calls.
111
 
    #
112
 
    # This code must go here. It cannot go anywhere in Bugzilla::CGI, because
113
 
    # it uses Template, and that causes various dependency loops.
114
 
    if (!$^C && Bugzilla->params->{"shutdownhtml"} 
115
 
        && lsearch(SHUTDOWNHTML_EXEMPT, basename($0)) == -1)
116
 
    {
117
 
        # Allow non-cgi scripts to exit silently (without displaying any
118
 
        # message), if desired. At this point, no DBI call has been made
119
 
        # yet, and no error will be returned if the DB is inaccessible.
120
 
        if (lsearch(SHUTDOWNHTML_EXIT_SILENTLY, basename($0)) > -1
121
 
            && !i_am_cgi())
122
 
        {
123
 
            exit;
124
 
        }
125
 
 
126
 
        # For security reasons, log out users when Bugzilla is down.
127
 
        # Bugzilla->login() is required to catch the logincookie, if any.
128
 
        my $user = Bugzilla->login(LOGIN_OPTIONAL);
129
 
        my $userid = $user->id;
130
 
        Bugzilla->logout();
131
 
 
132
 
        my $template = Bugzilla->template;
133
 
        my $vars = {};
134
 
        $vars->{'message'} = 'shutdown';
135
 
        $vars->{'userid'} = $userid;
136
 
        # Generate and return a message about the downtime, appropriately
137
 
        # for if we're a command-line script or a CGI script.
138
 
        my $extension;
139
 
        if (i_am_cgi() && (!Bugzilla->cgi->param('ctype')
140
 
                           || Bugzilla->cgi->param('ctype') eq 'html')) {
141
 
            $extension = 'html';
142
 
        }
143
 
        else {
144
 
            $extension = 'txt';
145
 
        }
146
 
        print Bugzilla->cgi->header() if i_am_cgi();
147
 
        my $t_output;
148
 
        $template->process("global/message.$extension.tmpl", $vars, \$t_output)
149
 
            || ThrowTemplateError($template->error);
150
 
        print $t_output . "\n";
151
 
        exit;
152
 
    }
153
 
}
154
 
 
155
 
init_page() if !$ENV{MOD_PERL};
156
 
 
157
 
#####################################################################
158
 
# Subroutines and Methods
159
 
#####################################################################
160
 
 
161
 
sub template {
162
 
    my $class = shift;
163
 
    request_cache()->{language} = "";
164
 
    request_cache()->{template} ||= Bugzilla::Template->create();
165
 
    return request_cache()->{template};
166
 
}
167
 
 
168
 
sub template_inner {
169
 
    my ($class, $lang) = @_;
170
 
    $lang = defined($lang) ? $lang : (request_cache()->{language} || "");
171
 
    request_cache()->{language} = $lang;
172
 
    request_cache()->{"template_inner_$lang"} ||= Bugzilla::Template->create();
173
 
    return request_cache()->{"template_inner_$lang"};
174
 
}
175
 
 
176
 
sub cgi {
177
 
    my $class = shift;
178
 
    request_cache()->{cgi} ||= new Bugzilla::CGI();
179
 
    return request_cache()->{cgi};
180
 
}
181
 
 
182
 
sub localconfig {
183
 
    request_cache()->{localconfig} ||= read_localconfig();
184
 
    return request_cache()->{localconfig};
185
 
}
186
 
 
187
 
sub params {
188
 
    my $class = shift;
189
 
    request_cache()->{params} ||= Bugzilla::Config::read_param_file();
190
 
    return request_cache()->{params};
191
 
}
192
 
 
193
 
sub user {
194
 
    my $class = shift;
195
 
    request_cache()->{user} ||= new Bugzilla::User;
196
 
    return request_cache()->{user};
197
 
}
198
 
 
199
 
sub set_user {
200
 
    my ($class, $user) = @_;
201
 
    $class->request_cache->{user} = $user;
202
 
}
203
 
 
204
 
sub sudoer {
205
 
    my $class = shift;    
206
 
    return request_cache()->{sudoer};
207
 
}
208
 
 
209
 
sub sudo_request {
210
 
    my $class = shift;
211
 
    my $new_user = shift;
212
 
    my $new_sudoer = shift;
213
 
 
214
 
    request_cache()->{user}   = $new_user;
215
 
    request_cache()->{sudoer} = $new_sudoer;
216
 
 
217
 
    # NOTE: If you want to log the start of an sudo session, do it here.
218
 
 
219
 
    return;
220
 
}
221
 
 
222
 
sub login {
223
 
    my ($class, $type) = @_;
224
 
 
225
 
    return Bugzilla->user if Bugzilla->user->id;
226
 
 
227
 
    my $authorizer = new Bugzilla::Auth();
228
 
    $type = LOGIN_REQUIRED if Bugzilla->cgi->param('GoAheadAndLogIn');
229
 
    if (!defined $type || $type == LOGIN_NORMAL) {
230
 
        $type = Bugzilla->params->{'requirelogin'} ? LOGIN_REQUIRED : LOGIN_NORMAL;
231
 
    }
232
 
    my $authenticated_user = $authorizer->login($type);
233
 
    
234
 
    # At this point, we now know if a real person is logged in.
235
 
    # We must now check to see if an sudo session is in progress.
236
 
    # For a session to be in progress, the following must be true:
237
 
    # 1: There must be a logged in user
238
 
    # 2: That user must be in the 'bz_sudoer' group
239
 
    # 3: There must be a valid value in the 'sudo' cookie
240
 
    # 4: A Bugzilla::User object must exist for the given cookie value
241
 
    # 5: That user must NOT be in the 'bz_sudo_protect' group
242
 
    my $sudo_cookie = $class->cgi->cookie('sudo');
243
 
    detaint_natural($sudo_cookie) if defined($sudo_cookie);
244
 
    my $sudo_target;
245
 
    $sudo_target = new Bugzilla::User($sudo_cookie) if defined($sudo_cookie);
246
 
    if (defined($authenticated_user)                 &&
247
 
        $authenticated_user->in_group('bz_sudoers')  &&
248
 
        defined($sudo_cookie)                        &&
249
 
        defined($sudo_target)                        &&
250
 
        !($sudo_target->in_group('bz_sudo_protect'))
251
 
       )
252
 
    {
253
 
        Bugzilla->set_user($sudo_target);
254
 
        request_cache()->{sudoer} = $authenticated_user;
255
 
        # And make sure that both users have the same Auth object,
256
 
        # since we never call Auth::login for the sudo target.
257
 
        $sudo_target->set_authorizer($authenticated_user->authorizer);
258
 
 
259
 
        # NOTE: If you want to do any special logging, do it here.
260
 
    }
261
 
    else {
262
 
        Bugzilla->set_user($authenticated_user);
263
 
    }
264
 
    
265
 
    return Bugzilla->user;
266
 
}
267
 
 
268
 
sub logout {
269
 
    my ($class, $option) = @_;
270
 
 
271
 
    # If we're not logged in, go away
272
 
    return unless user->id;
273
 
 
274
 
    $option = LOGOUT_CURRENT unless defined $option;
275
 
    Bugzilla::Auth::Persist::Cookie->logout({type => $option});
276
 
    Bugzilla->logout_request() unless $option eq LOGOUT_KEEP_CURRENT;
277
 
}
278
 
 
279
 
sub logout_user {
280
 
    my ($class, $user) = @_;
281
 
    # When we're logging out another user we leave cookies alone, and
282
 
    # therefore avoid calling Bugzilla->logout() directly.
283
 
    Bugzilla::Auth::Persist::Cookie->logout({user => $user});
284
 
}
285
 
 
286
 
# just a compatibility front-end to logout_user that gets a user by id
287
 
sub logout_user_by_id {
288
 
    my ($class, $id) = @_;
289
 
    my $user = new Bugzilla::User($id);
290
 
    $class->logout_user($user);
291
 
}
292
 
 
293
 
# hack that invalidates credentials for a single request
294
 
sub logout_request {
295
 
    delete request_cache()->{user};
296
 
    delete request_cache()->{sudoer};
297
 
    # We can't delete from $cgi->cookie, so logincookie data will remain
298
 
    # there. Don't rely on it: use Bugzilla->user->login instead!
299
 
}
300
 
 
301
 
sub dbh {
302
 
    my $class = shift;
303
 
 
304
 
    # If we're not connected, then we must want the main db
305
 
    request_cache()->{dbh} ||= request_cache()->{dbh_main} 
306
 
        = Bugzilla::DB::connect_main();
307
 
 
308
 
    return request_cache()->{dbh};
309
 
}
310
 
 
311
 
sub error_mode {
312
 
    my $class = shift;
313
 
    my $newval = shift;
314
 
    if (defined $newval) {
315
 
        request_cache()->{error_mode} = $newval;
316
 
    }
317
 
    return request_cache()->{error_mode}
318
 
        || Bugzilla::Constants::ERROR_MODE_WEBPAGE;
319
 
}
320
 
 
321
 
sub usage_mode {
322
 
    my $class = shift;
323
 
    my $newval = shift;
324
 
    if (defined $newval) {
325
 
        if ($newval == USAGE_MODE_BROWSER) {
326
 
            $class->error_mode(ERROR_MODE_WEBPAGE);
327
 
        }
328
 
        elsif ($newval == USAGE_MODE_CMDLINE) {
329
 
            $class->error_mode(ERROR_MODE_DIE);
330
 
        }
331
 
        elsif ($newval == USAGE_MODE_WEBSERVICE) {
332
 
            $class->error_mode(ERROR_MODE_DIE_SOAP_FAULT);
333
 
        }
334
 
        elsif ($newval == USAGE_MODE_EMAIL) {
335
 
            $class->error_mode(ERROR_MODE_DIE);
336
 
        }
337
 
        else {
338
 
            ThrowCodeError('usage_mode_invalid',
339
 
                           {'invalid_usage_mode', $newval});
340
 
        }
341
 
        request_cache()->{usage_mode} = $newval;
342
 
    }
343
 
    return request_cache()->{usage_mode}
344
 
        || Bugzilla::Constants::USAGE_MODE_BROWSER;
345
 
}
346
 
 
347
 
sub installation_mode {
348
 
    my ($class, $newval) = @_;
349
 
    ($class->request_cache->{installation_mode} = $newval) if defined $newval;
350
 
    return $class->request_cache->{installation_mode}
351
 
        || INSTALLATION_MODE_INTERACTIVE;
352
 
}
353
 
 
354
 
sub installation_answers {
355
 
    my ($class, $filename) = @_;
356
 
    if ($filename) {
357
 
        my $s = new Safe;
358
 
        $s->rdo($filename);
359
 
 
360
 
        die "Error reading $filename: $!" if $!;
361
 
        die "Error evaluating $filename: $@" if $@;
362
 
 
363
 
        # Now read the param back out from the sandbox
364
 
        $class->request_cache->{installation_answers} = $s->varglob('answer');
365
 
    }
366
 
    return $class->request_cache->{installation_answers} || {};
367
 
}
368
 
 
369
 
sub switch_to_shadow_db {
370
 
    my $class = shift;
371
 
 
372
 
    if (!request_cache()->{dbh_shadow}) {
373
 
        if (Bugzilla->params->{'shadowdb'}) {
374
 
            request_cache()->{dbh_shadow} = Bugzilla::DB::connect_shadow();
375
 
        } else {
376
 
            request_cache()->{dbh_shadow} = request_cache()->{dbh_main};
377
 
        }
378
 
    }
379
 
 
380
 
    request_cache()->{dbh} = request_cache()->{dbh_shadow};
381
 
    # we have to return $class->dbh instead of {dbh} as
382
 
    # {dbh_shadow} may be undefined if no shadow DB is used
383
 
    # and no connection to the main DB has been established yet.
384
 
    return $class->dbh;
385
 
}
386
 
 
387
 
sub switch_to_main_db {
388
 
    my $class = shift;
389
 
 
390
 
    request_cache()->{dbh} = request_cache()->{dbh_main};
391
 
    # We have to return $class->dbh instead of {dbh} as
392
 
    # {dbh_main} may be undefined if no connection to the main DB
393
 
    # has been established yet.
394
 
    return $class->dbh;
395
 
}
396
 
 
397
 
sub get_fields {
398
 
    my $class = shift;
399
 
    my $criteria = shift;
400
 
    # This function may be called during installation, and Field::match
401
 
    # may fail at that time. so we want to return an empty list in that
402
 
    # case.
403
 
    my $fields = eval { Bugzilla::Field->match($criteria) } || [];
404
 
    return @$fields;
405
 
}
406
 
 
407
 
sub custom_field_names {
408
 
    # Get a list of custom fields and convert it into a list of their names.
409
 
    return map($_->{name}, 
410
 
               @{Bugzilla::Field->match({ custom=>1, obsolete=>0 })});
411
 
}
412
 
 
413
 
sub hook_args {
414
 
    my ($class, $args) = @_;
415
 
    $class->request_cache->{hook_args} = $args if $args;
416
 
    return $class->request_cache->{hook_args};
417
 
}
418
 
 
419
 
sub request_cache {
420
 
    if ($ENV{MOD_PERL}) {
421
 
        require Apache2::RequestUtil;
422
 
        return Apache2::RequestUtil->request->pnotes();
423
 
    }
424
 
    return $_request_cache;
425
 
}
426
 
 
427
 
# Private methods
428
 
 
429
 
# Per process cleanup
430
 
sub _cleanup {
431
 
 
432
 
    # When we support transactions, need to ->rollback here
433
 
    my $main   = request_cache()->{dbh_main};
434
 
    my $shadow = request_cache()->{dbh_shadow};
435
 
    $main->disconnect if $main;
436
 
    $shadow->disconnect if $shadow && Bugzilla->params->{"shadowdb"};
437
 
    undef $_request_cache;
438
 
}
439
 
 
440
 
sub END {
441
 
    # Bugzilla.pm cannot compile in mod_perl.pl if this runs.
442
 
    _cleanup() unless $ENV{MOD_PERL};
443
 
}
444
 
 
445
 
1;
446
 
 
447
 
__END__
448
 
 
449
 
=head1 NAME
450
 
 
451
 
Bugzilla - Semi-persistent collection of various objects used by scripts
452
 
and modules
453
 
 
454
 
=head1 SYNOPSIS
455
 
 
456
 
  use Bugzilla;
457
 
 
458
 
  sub someModulesSub {
459
 
    Bugzilla->dbh->prepare(...);
460
 
    Bugzilla->template->process(...);
461
 
  }
462
 
 
463
 
=head1 DESCRIPTION
464
 
 
465
 
Several Bugzilla 'things' are used by a variety of modules and scripts. This
466
 
includes database handles, template objects, and so on.
467
 
 
468
 
This module is a singleton intended as a central place to store these objects.
469
 
This approach has several advantages:
470
 
 
471
 
=over 4
472
 
 
473
 
=item *
474
 
 
475
 
They're not global variables, so we don't have issues with them staying around
476
 
with mod_perl
477
 
 
478
 
=item *
479
 
 
480
 
Everything is in one central place, so it's easy to access, modify, and maintain
481
 
 
482
 
=item *
483
 
 
484
 
Code in modules can get access to these objects without having to have them
485
 
all passed from the caller, and the caller's caller, and....
486
 
 
487
 
=item *
488
 
 
489
 
We can reuse objects across requests using mod_perl where appropriate (eg
490
 
templates), whilst destroying those which are only valid for a single request
491
 
(such as the current user)
492
 
 
493
 
=back
494
 
 
495
 
Note that items accessible via this object are demand-loaded when requested.
496
 
 
497
 
For something to be added to this object, it should either be able to benefit
498
 
from persistence when run under mod_perl (such as the a C<template> object),
499
 
or should be something which is globally required by a large ammount of code
500
 
(such as the current C<user> object).
501
 
 
502
 
=head1 METHODS
503
 
 
504
 
Note that all C<Bugzilla> functionality is method based; use C<Bugzilla-E<gt>dbh>
505
 
rather than C<Bugzilla::dbh>. Nothing cares about this now, but don't rely on
506
 
that.
507
 
 
508
 
=over 4
509
 
 
510
 
=item C<template>
511
 
 
512
 
The current C<Template> object, to be used for output
513
 
 
514
 
=item C<template_inner>
515
 
 
516
 
If you ever need a L<Bugzilla::Template> object while you're already
517
 
processing a template, use this. Also use it if you want to specify
518
 
the language to use. If no argument is passed, it uses the last
519
 
language set. If the argument is "" (empty string), the language is
520
 
reset to the current one (the one used by Bugzilla->template).
521
 
 
522
 
=item C<cgi>
523
 
 
524
 
The current C<cgi> object. Note that modules should B<not> be using this in
525
 
general. Not all Bugzilla actions are cgi requests. Its useful as a convenience
526
 
method for those scripts/templates which are only use via CGI, though.
527
 
 
528
 
=item C<user>
529
 
 
530
 
C<undef> if there is no currently logged in user or if the login code has not
531
 
yet been run.  If an sudo session is in progress, the C<Bugzilla::User>
532
 
corresponding to the person who is being impersonated.  If no session is in
533
 
progress, the current C<Bugzilla::User>.
534
 
 
535
 
=item C<set_user>
536
 
 
537
 
Allows you to directly set what L</user> will return. You can use this
538
 
if you want to bypass L</login> for some reason and directly "log in"
539
 
a specific L<Bugzilla::User>. Be careful with it, though!
540
 
 
541
 
=item C<sudoer>
542
 
 
543
 
C<undef> if there is no currently logged in user, the currently logged in user
544
 
is not in the I<sudoer> group, or there is no session in progress.  If an sudo
545
 
session is in progress, returns the C<Bugzilla::User> object corresponding to
546
 
the person who logged in and initiated the session.  If no session is in
547
 
progress, returns the C<Bugzilla::User> object corresponding to the currently
548
 
logged in user.
549
 
 
550
 
=item C<sudo_request>
551
 
This begins an sudo session for the current request.  It is meant to be 
552
 
used when a session has just started.  For normal use, sudo access should 
553
 
normally be set at login time.
554
 
 
555
 
=item C<login>
556
 
 
557
 
Logs in a user, returning a C<Bugzilla::User> object, or C<undef> if there is
558
 
no logged in user. See L<Bugzilla::Auth|Bugzilla::Auth>, and
559
 
L<Bugzilla::User|Bugzilla::User>.
560
 
 
561
 
=item C<logout($option)>
562
 
 
563
 
Logs out the current user, which involves invalidating user sessions and
564
 
cookies. Three options are available from
565
 
L<Bugzilla::Constants|Bugzilla::Constants>: LOGOUT_CURRENT (the
566
 
default), LOGOUT_ALL or LOGOUT_KEEP_CURRENT.
567
 
 
568
 
=item C<logout_user($user)>
569
 
 
570
 
Logs out the specified user (invalidating all his sessions), taking a
571
 
Bugzilla::User instance.
572
 
 
573
 
=item C<logout_by_id($id)>
574
 
 
575
 
Logs out the user with the id specified. This is a compatibility
576
 
function to be used in callsites where there is only a userid and no
577
 
Bugzilla::User instance.
578
 
 
579
 
=item C<logout_request>
580
 
 
581
 
Essentially, causes calls to C<Bugzilla-E<gt>user> to return C<undef>. This has the
582
 
effect of logging out a user for the current request only; cookies and
583
 
database sessions are left intact.
584
 
 
585
 
=item C<error_mode>
586
 
 
587
 
Call either C<Bugzilla->error_mode(Bugzilla::Constants::ERROR_MODE_DIE)>
588
 
or C<Bugzilla->error_mode(Bugzilla::Constants::ERROR_MODE_DIE_SOAP_FAULT)> to
589
 
change this flag's default of C<Bugzilla::Constants::ERROR_MODE_WEBPAGE> and to
590
 
indicate that errors should be passed to error mode specific error handlers
591
 
rather than being sent to a browser and finished with an exit().
592
 
 
593
 
This is useful, for example, to keep C<eval> blocks from producing wild HTML
594
 
on errors, making it easier for you to catch them.
595
 
(Remember to reset the error mode to its previous value afterwards, though.)
596
 
 
597
 
C<Bugzilla->error_mode> will return the current state of this flag.
598
 
 
599
 
Note that C<Bugzilla->error_mode> is being called by C<Bugzilla->usage_mode> on
600
 
usage mode changes.
601
 
 
602
 
=item C<usage_mode>
603
 
 
604
 
Call either C<Bugzilla->usage_mode(Bugzilla::Constants::USAGE_MODE_CMDLINE)>
605
 
or C<Bugzilla->usage_mode(Bugzilla::Constants::USAGE_MODE_WEBSERVICE)> near the
606
 
beginning of your script to change this flag's default of
607
 
C<Bugzilla::Constants::USAGE_MODE_BROWSER> and to indicate that Bugzilla is
608
 
being called in a non-interactive manner.
609
 
This influences error handling because on usage mode changes, C<usage_mode>
610
 
calls C<Bugzilla->error_mode> to set an error mode which makes sense for the
611
 
usage mode.
612
 
 
613
 
C<Bugzilla->usage_mode> will return the current state of this flag.
614
 
 
615
 
=item C<installation_mode>
616
 
 
617
 
Determines whether or not installation should be silent. See 
618
 
L<Bugzilla::Constants> for the C<INSTALLATION_MODE> constants.
619
 
 
620
 
=item C<installation_answers>
621
 
 
622
 
Returns a hashref representing any "answers" file passed to F<checksetup.pl>,
623
 
used to automatically answer or skip prompts.
624
 
 
625
 
=item C<dbh>
626
 
 
627
 
The current database handle. See L<DBI>.
628
 
 
629
 
=item C<switch_to_shadow_db>
630
 
 
631
 
Switch from using the main database to using the shadow database.
632
 
 
633
 
=item C<switch_to_main_db>
634
 
 
635
 
Change the database object to refer to the main database.
636
 
 
637
 
=item C<params>
638
 
 
639
 
The current Parameters of Bugzilla, as a hashref. If C<data/params>
640
 
does not exist, then we return an empty hashref. If C<data/params>
641
 
is unreadable or is not valid perl, we C<die>.
642
 
 
643
 
=item C<hook_args>
644
 
 
645
 
If you are running inside a code hook (see L<Bugzilla::Hook>) this
646
 
is how you get the arguments passed to the hook.
647
 
 
648
 
=back