post_bug.cgi 7 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
    work_time
    productive_time
114 115
    )
);
116 117
my %bug_params;
foreach my $field (@bug_fields) {
118
  $bug_params{$field} = $cgi->param($field);
119
}
120
foreach my $field (qw(cc groups)) {
121 122
  next if !$cgi->should_set($field);
  $bug_params{$field} = [$cgi->param($field)];
123 124
}
$bug_params{'comment'} = $comment;
125

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

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

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

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

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

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

157 158 159
# 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.
160

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

if ($data_fh || $attach_text) {
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 204 205
  $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';
  }
206 207
}

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

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

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

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

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

# Sending emails for any referenced bugs.
234 235 236 237
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);
238 239
}

240 241
$vars->{sentmail} = \@all_mail_results;

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

248
1;