Rubber-stamped by Brady Eidson.
[webbrowser.git] / BugsSite / post_bug.cgi
blob2920df394f15ed0c7103831c7742480afd83bccc
1 #!/usr/bin/env perl -wT
2 # -*- Mode: perl; indent-tabs-mode: nil -*-
4 # The contents of this file are subject to the Mozilla Public
5 # License Version 1.1 (the "License"); you may not use this file
6 # except in compliance with the License. You may obtain a copy of
7 # the License at http://www.mozilla.org/MPL/
9 # Software distributed under the License is distributed on an "AS
10 # IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
11 # implied. See the License for the specific language governing
12 # rights and limitations under the License.
14 # The Original Code is the Bugzilla Bug Tracking System.
16 # The Initial Developer of the Original Code is Netscape Communications
17 # Corporation. Portions created by Netscape are
18 # Copyright (C) 1998 Netscape Communications Corporation. All
19 # Rights Reserved.
21 # Contributor(s): Terry Weissman <terry@mozilla.org>
22 # Dan Mosedale <dmose@mozilla.org>
23 # Joe Robins <jmrobins@tgix.com>
24 # Gervase Markham <gerv@gerv.net>
25 # Marc Schumann <wurblzap@gmail.com>
27 use strict;
28 use lib qw(. lib);
30 use Bugzilla;
31 use Bugzilla::Attachment;
32 use Bugzilla::BugMail;
33 use Bugzilla::Constants;
34 use Bugzilla::Util;
35 use Bugzilla::Error;
36 use Bugzilla::Bug;
37 use Bugzilla::User;
38 use Bugzilla::Field;
39 use Bugzilla::Hook;
40 use Bugzilla::Product;
41 use Bugzilla::Component;
42 use Bugzilla::Keyword;
43 use Bugzilla::Token;
44 use Bugzilla::Flag;
46 my $user = Bugzilla->login(LOGIN_REQUIRED);
48 my $cgi = Bugzilla->cgi;
49 my $dbh = Bugzilla->dbh;
50 my $template = Bugzilla->template;
51 my $vars = {};
53 ######################################################################
54 # Main Script
55 ######################################################################
57 # redirect to enter_bug if no field is passed.
58 print $cgi->redirect(correct_urlbase() . 'enter_bug.cgi') unless $cgi->param();
60 # Detect if the user already used the same form to submit a bug
61 my $token = trim($cgi->param('token'));
62 if ($token) {
63 my ($creator_id, $date, $old_bug_id) = Bugzilla::Token::GetTokenData($token);
64 unless ($creator_id
65 && ($creator_id == $user->id)
66 && ($old_bug_id =~ "^createbug:"))
68 # The token is invalid.
69 ThrowUserError('token_does_not_exist');
72 $old_bug_id =~ s/^createbug://;
74 if ($old_bug_id && (!$cgi->param('ignore_token')
75 || ($cgi->param('ignore_token') != $old_bug_id)))
77 $vars->{'bugid'} = $old_bug_id;
78 $vars->{'allow_override'} = defined $cgi->param('ignore_token') ? 0 : 1;
80 print $cgi->header();
81 $template->process("bug/create/confirm-create-dupe.html.tmpl", $vars)
82 || ThrowTemplateError($template->error());
83 exit;
87 # do a match on the fields if applicable
89 &Bugzilla::User::match_field ($cgi, {
90 'cc' => { 'type' => 'multi' },
91 'assigned_to' => { 'type' => 'single' },
92 'qa_contact' => { 'type' => 'single' },
93 '^requestee_type-(\d+)$' => { 'type' => 'multi' },
94 });
96 if (defined $cgi->param('maketemplate')) {
97 $vars->{'url'} = $cgi->canonicalise_query('token');
98 $vars->{'short_desc'} = $cgi->param('short_desc');
100 print $cgi->header();
101 $template->process("bug/create/make-template.html.tmpl", $vars)
102 || ThrowTemplateError($template->error());
103 exit;
106 umask 0;
108 # get current time
109 my $timestamp = $dbh->selectrow_array(q{SELECT NOW()});
111 # Group Validation
112 my @selected_groups;
113 foreach my $group (grep(/^bit-\d+$/, $cgi->param())) {
114 $group =~ /^bit-(\d+)$/;
115 push(@selected_groups, $1);
118 # The format of the initial comment can be structured by adding fields to the
119 # enter_bug template and then referencing them in the comment template.
120 my $comment;
121 my $format = $template->get_format("bug/create/comment",
122 scalar($cgi->param('format')), "txt");
123 $template->process($format->{'template'}, $vars, \$comment)
124 || ThrowTemplateError($template->error());
126 # Include custom fields editable on bug creation.
127 my @custom_bug_fields = grep {$_->type != FIELD_TYPE_MULTI_SELECT && $_->enter_bug}
128 Bugzilla->active_custom_fields;
130 # Undefined custom fields are ignored to ensure they will get their default
131 # value (e.g. "---" for custom single select fields).
132 my @bug_fields = grep { defined $cgi->param($_->name) } @custom_bug_fields;
133 @bug_fields = map { $_->name } @bug_fields;
135 push(@bug_fields, qw(
136 product
137 component
139 assigned_to
140 qa_contact
142 alias
143 blocked
144 commentprivacy
145 bug_file_loc
146 bug_severity
147 bug_status
148 dependson
149 keywords
150 short_desc
151 op_sys
152 priority
153 rep_platform
154 version
155 target_milestone
156 status_whiteboard
158 estimated_time
159 deadline
161 my %bug_params;
162 foreach my $field (@bug_fields) {
163 $bug_params{$field} = $cgi->param($field);
165 $bug_params{'creation_ts'} = $timestamp;
166 $bug_params{'cc'} = [$cgi->param('cc')];
167 $bug_params{'groups'} = \@selected_groups;
168 $bug_params{'comment'} = $comment;
170 my @multi_selects = grep {$_->type == FIELD_TYPE_MULTI_SELECT && $_->enter_bug}
171 Bugzilla->active_custom_fields;
173 foreach my $field (@multi_selects) {
174 $bug_params{$field->name} = [$cgi->param($field->name)];
177 my $bug = Bugzilla::Bug->create(\%bug_params);
179 # Get the bug ID back.
180 my $id = $bug->bug_id;
182 # Set Version cookie, but only if the user actually selected
183 # a version on the page.
184 if (defined $cgi->param('version')) {
185 $cgi->send_cookie(-name => "VERSION-" . $bug->product,
186 -value => $bug->version,
187 -expires => "Fri, 01-Jan-2038 00:00:00 GMT");
190 # We don't have to check if the user can see the bug, because a user filing
191 # a bug can always see it. You can't change reporter_accessible until
192 # after the bug is filed.
194 # Add an attachment if requested.
195 if (defined($cgi->upload('data')) || $cgi->param('attachurl')) {
196 $cgi->param('isprivate', $cgi->param('commentprivacy'));
197 my $attachment = Bugzilla::Attachment->insert_attachment_for_bug(!THROW_ERROR,
198 $bug, $user, $timestamp, $vars);
200 if ($attachment) {
201 # Update the comment to include the new attachment ID.
202 # This string is hardcoded here because Template::quoteUrls()
203 # expects to find this exact string.
204 my $new_comment = "Created an attachment (id=" . $attachment->id . ")\n" .
205 $attachment->description . "\n";
206 # We can use $bug->longdescs here because we are sure that the bug
207 # description is of type CMT_NORMAL. No need to include it if it's
208 # empty, though.
209 if ($bug->longdescs->[0]->{'body'} !~ /^\s+$/) {
210 $new_comment .= "\n" . $bug->longdescs->[0]->{'body'};
212 $bug->update_comment($bug->longdescs->[0]->{'id'}, $new_comment);
214 else {
215 $vars->{'message'} = 'attachment_creation_failed';
218 # Determine if Patch Viewer is installed, for Diff link
219 eval {
220 require PatchReader;
221 $vars->{'patchviewerinstalled'} = 1;
225 # Add flags, if any. To avoid dying if something goes wrong
226 # while processing flags, we will eval() flag validation.
227 # This requires errors to die().
228 # XXX: this can go away as soon as flag validation is able to
229 # fail without dying.
230 my $error_mode_cache = Bugzilla->error_mode;
231 Bugzilla->error_mode(ERROR_MODE_DIE);
232 eval {
233 Bugzilla::Flag::validate($id, undef, SKIP_REQUESTEE_ON_ERROR);
234 Bugzilla::Flag->process($bug, undef, $timestamp, $vars);
236 Bugzilla->error_mode($error_mode_cache);
237 if ($@) {
238 $vars->{'message'} = 'flag_creation_failed';
239 $vars->{'flag_creation_error'} = $@;
242 # Email everyone the details of the new bug
243 $vars->{'mailrecipients'} = {'changer' => $user->login};
245 $vars->{'id'} = $id;
246 $vars->{'bug'} = $bug;
248 Bugzilla::Hook::process("post_bug-after_creation", { vars => $vars });
250 ThrowCodeError("bug_error", { bug => $bug }) if $bug->error;
252 $vars->{'sentmail'} = [];
254 push (@{$vars->{'sentmail'}}, { type => 'created',
255 id => $id,
258 foreach my $i (@{$bug->dependson || []}, @{$bug->blocked || []}) {
259 push (@{$vars->{'sentmail'}}, { type => 'dep', id => $i, });
262 my @bug_list;
263 if ($cgi->cookie("BUGLIST")) {
264 @bug_list = split(/:/, $cgi->cookie("BUGLIST"));
266 $vars->{'bug_list'} = \@bug_list;
267 $vars->{'use_keywords'} = 1 if Bugzilla::Keyword::keyword_count();
269 if ($token) {
270 trick_taint($token);
271 $dbh->do('UPDATE tokens SET eventdata = ? WHERE token = ?', undef,
272 ("createbug:$id", $token));
275 if (Bugzilla->usage_mode == USAGE_MODE_EMAIL) {
276 Bugzilla::BugMail::Send($id, $vars->{'mailrecipients'});
278 else {
279 print $cgi->header();
280 $template->process("bug/create/created.html.tmpl", $vars)
281 || ThrowTemplateError($template->error());