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
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>
31 use Bugzilla
::Attachment
;
32 use Bugzilla
::BugMail
;
33 use Bugzilla
::Constants
;
40 use Bugzilla
::Product
;
41 use Bugzilla
::Component
;
42 use Bugzilla
::Keyword
;
46 my $user = Bugzilla
->login(LOGIN_REQUIRED
);
48 my $cgi = Bugzilla
->cgi;
49 my $dbh = Bugzilla
->dbh;
50 my $template = Bugzilla
->template;
53 ######################################################################
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'));
63 my ($creator_id, $date, $old_bug_id) = Bugzilla
::Token
::GetTokenData
($token);
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;
81 $template->process("bug/create/confirm-create-dupe.html.tmpl", $vars)
82 || ThrowTemplateError
($template->error());
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' },
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());
109 my $timestamp = $dbh->selectrow_array(q{SELECT NOW()});
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.
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(
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);
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
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);
215 $vars->{'message'} = 'attachment_creation_failed';
218 # Determine if Patch Viewer is installed, for Diff link
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
);
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);
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};
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',
258 foreach my $i (@
{$bug->dependson || []}, @
{$bug->blocked || []}) {
259 push (@
{$vars->{'sentmail'}}, { type
=> 'dep', id
=> $i, });
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
();
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'});
279 print $cgi->header();
280 $template->process("bug/create/created.html.tmpl", $vars)
281 || ThrowTemplateError
($template->error());