post_bug.cgi 6.97 KB
Newer Older
1
#!/usr/bin/perl -T
2 3 4
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
terry%netscape.com's avatar
terry%netscape.com committed
5
#
6 7
# This Source Code Form is "Incompatible With Secondary Licenses", as
# defined by the Mozilla Public License, v. 2.0.
terry%netscape.com's avatar
terry%netscape.com committed
8

9
use 5.10.1;
10
use strict;
11 12
use warnings;

13
use lib qw(. lib);
14

15
use Bugzilla;
16
use Bugzilla::Attachment;
17
use Bugzilla::BugMail;
18
use Bugzilla::Constants;
19
use Bugzilla::Util;
20
use Bugzilla::Error;
21
use Bugzilla::Bug;
22
use Bugzilla::User;
23
use Bugzilla::Hook;
24
use Bugzilla::Token;
25
use Bugzilla::Flag;
26

27 28
use List::MoreUtils qw(uniq);

29
my $user = Bugzilla->login(LOGIN_REQUIRED);
30

31 32
my $cgi      = Bugzilla->cgi;
my $dbh      = Bugzilla->dbh;
33
my $template = Bugzilla->template;
34
my $vars     = {};
35

36 37 38 39
######################################################################
# Main Script
######################################################################

40
# redirect to enter_bug if no field is passed.
41
unless ($cgi->param()) {
42 43
  print $cgi->redirect(correct_urlbase() . 'enter_bug.cgi');
  exit;
44
}
45

46 47
# Detect if the user already used the same form to submit a bug
my $token = trim($cgi->param('token'));
48
check_token_data($token, 'create_bug', 'index.cgi');
49

50
# do a match on the fields if applicable
51 52 53 54
Bugzilla::User::match_field({
  'cc'          => {'type' => 'multi'},
  'assigned_to' => {'type' => 'single'},
  'qa_contact'  => {'type' => 'single'},
55
});
56

57
if (defined $cgi->param('maketemplate')) {
58 59 60 61 62 63 64
  $vars->{'url'}        = $cgi->canonicalise_query('token');
  $vars->{'short_desc'} = $cgi->param('short_desc');

  print $cgi->header();
  $template->process("bug/create/make-template.html.tmpl", $vars)
    || ThrowTemplateError($template->error());
  exit;
terry%netscape.com's avatar
terry%netscape.com committed
65 66
}

67 68 69
# The format of the initial comment can be structured by adding fields to the
# enter_bug template and then referencing them in the comment template.
my $comment;
70 71 72
my $format
  = $template->get_format("bug/create/comment", scalar($cgi->param('format')),
  "txt");
73
$template->process($format->{'template'}, $vars, \$comment)
74
  || ThrowTemplateError($template->error());
75

76
# Include custom fields editable on bug creation.
77 78 79
my @custom_bug_fields
  = grep { $_->type != FIELD_TYPE_MULTI_SELECT && $_->enter_bug }
  Bugzilla->active_custom_fields;
80

81 82 83 84
# Undefined custom fields are ignored to ensure they will get their default
# value (e.g. "---" for custom single select fields).
my @bug_fields = grep { defined $cgi->param($_->name) } @custom_bug_fields;
@bug_fields = map { $_->name } @bug_fields;
85

86 87
push(
  @bug_fields, qw(
88 89 90 91 92 93 94
    product
    component

    assigned_to
    qa_contact

    alias
95
    blocked
96
    comment_is_private
97 98 99
    bug_file_loc
    bug_severity
    bug_status
100
    dependson
101
    keywords
102 103 104 105 106 107 108
    short_desc
    op_sys
    priority
    rep_platform
    version
    target_milestone
    status_whiteboard
109
    see_also
110 111
    estimated_time
    deadline
112 113
    )
);
114 115
my %bug_params;
foreach my $field (@bug_fields) {
116
  $bug_params{$field} = $cgi->param($field);
117
}
118
foreach my $field (qw(cc groups)) {
119 120
  next if !$cgi->should_set($field);
  $bug_params{$field} = [$cgi->param($field)];
121 122
}
$bug_params{'comment'} = $comment;
123

124 125 126
my @multi_selects
  = grep { $_->type == FIELD_TYPE_MULTI_SELECT && $_->enter_bug }
  Bugzilla->active_custom_fields;
127

128
foreach my $field (@multi_selects) {
129 130
  next if !$cgi->should_set($field->name);
  $bug_params{$field->name} = [$cgi->param($field->name)];
131 132
}

133
my $bug = Bugzilla::Bug->create(\%bug_params);
134

135
# Get the bug ID back and delete the token used to create this bug.
136
my $id = $bug->bug_id;
137 138
delete_token($token);

139 140
# We do this directly from the DB because $bug->creation_ts has the seconds
# formatted out of it (which should be fixed some day).
141 142 143
my $timestamp
  = $dbh->selectrow_array('SELECT creation_ts FROM bugs WHERE bug_id = ?',
  undef, $id);
terry%netscape.com's avatar
terry%netscape.com committed
144

145 146 147
# Set Version cookie, but only if the user actually selected
# a version on the page.
if (defined $cgi->param('version')) {
148 149 150 151 152
  $cgi->send_cookie(
    -name    => "VERSION-" . $bug->product,
    -value   => $bug->version,
    -expires => "Fri, 01-Jan-2038 00:00:00 GMT"
  );
153 154
}

155 156 157
# We don't have to check if the user can see the bug, because a user filing
# a bug can always see it. You can't change reporter_accessible until
# after the bug is filed.
158

159
# Add an attachment if requested.
160
my $data_fh     = $cgi->upload('data');
161 162 163
my $attach_text = $cgi->param('attach_text');

if ($data_fh || $attach_text) {
164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203
  $cgi->param('isprivate', $cgi->param('comment_is_private'));

  # Must be called before create() as it may alter $cgi->param('ispatch').
  my $content_type = Bugzilla::Attachment::get_content_type();
  my $attachment;

  # If the attachment cannot be successfully added to the bug,
  # we notify the user, but we don't interrupt the bug creation process.
  my $error_mode_cache = Bugzilla->error_mode;
  Bugzilla->error_mode(ERROR_MODE_DIE);
  eval {
    $attachment = Bugzilla::Attachment->create({
      bug         => $bug,
      creation_ts => $timestamp,
      data        => $attach_text || $data_fh,
      description => scalar $cgi->param('description'),
      filename    => $attach_text ? "file_$id.txt" : $data_fh,
      ispatch     => scalar $cgi->param('ispatch'),
      isprivate   => scalar $cgi->param('isprivate'),
      mimetype    => $content_type,
    });
  };
  Bugzilla->error_mode($error_mode_cache);

  if ($attachment) {

    # Set attachment flags.
    my ($flags, $new_flags)
      = Bugzilla::Flag->extract_flags_from_cgi($bug, $attachment, $vars,
      SKIP_REQUESTEE_ON_ERROR);
    $attachment->set_flags($flags, $new_flags);
    $attachment->update($timestamp);
    my $comment = $bug->comments->[0];
    $comment->set_all(
      {type => CMT_ATTACHMENT_CREATED, extra_data => $attachment->id});
    $comment->update();
  }
  else {
    $vars->{'message'} = 'attachment_creation_failed';
  }
204 205
}

206
# Set bug flags.
207 208 209
my ($flags, $new_flags)
  = Bugzilla::Flag->extract_flags_from_cgi($bug, undef, $vars,
  SKIP_REQUESTEE_ON_ERROR);
210 211
$bug->set_flags($flags, $new_flags);
$bug->update($timestamp);
212

213
$vars->{'id'}  = $id;
214
$vars->{'bug'} = $bug;
terry%netscape.com's avatar
terry%netscape.com committed
215

216
Bugzilla::Hook::process('post_bug_after_creation', {vars => $vars});
217

218
my $recipients = {changer => $user};
219
my $bug_sent   = Bugzilla::BugMail::Send($id, $recipients);
220 221 222
$bug_sent->{type} = 'created';
$bug_sent->{id}   = $id;
my @all_mail_results = ($bug_sent);
223

224
foreach my $dep (@{$bug->dependson || []}, @{$bug->blocked || []}) {
225 226 227 228
  my $dep_sent = Bugzilla::BugMail::Send($dep, $recipients);
  $dep_sent->{type} = 'dep';
  $dep_sent->{id}   = $dep;
  push(@all_mail_results, $dep_sent);
229
}
230 231

# Sending emails for any referenced bugs.
232 233 234 235
foreach my $ref_bug_id (uniq @{$bug->{see_also_changes} || []}) {
  my $ref_sent = Bugzilla::BugMail::Send($ref_bug_id, $recipients);
  $ref_sent->{id} = $ref_bug_id;
  push(@all_mail_results, $ref_sent);
236 237
}

238 239
$vars->{sentmail} = \@all_mail_results;

240
$format = $template->get_format("bug/create/created",
241
  scalar($cgi->param('created-format')), "html");
242
print $cgi->header();
243
$template->process($format->{'template'}, $vars)
244
  || ThrowTemplateError($template->error());
245

246
1;