Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
bugzilla
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
etersoft
bugzilla
Commits
89cf83ec
Commit
89cf83ec
authored
Aug 09, 2011
by
Max Kanat-Alexander
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Bug 622203 - Allow filing closed bugs via the WebService
r=dkl, a=mkanat
parent
b308699b
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
90 additions
and
36 deletions
+90
-36
Bug.pm
Bugzilla/Bug.pm
+72
-31
Bug.pm
Bugzilla/WebService/Bug.pm
+8
-0
editworkflow.cgi
editworkflow.cgi
+1
-1
edit.html.tmpl
template/en/default/admin/workflow/edit.html.tmpl
+1
-1
user-error.html.tmpl
template/en/default/global/user-error.html.tmpl
+8
-3
No files found.
Bugzilla/Bug.pm
View file @
89cf83ec
...
@@ -124,6 +124,7 @@ sub VALIDATORS {
...
@@ -124,6 +124,7 @@ sub VALIDATORS {
my
$validators
=
{
my
$validators
=
{
alias
=>
\&
_check_alias
,
alias
=>
\&
_check_alias
,
assigned_to
=>
\&
_check_assigned_to
,
assigned_to
=>
\&
_check_assigned_to
,
blocked
=>
\&
_check_dependencies
,
bug_file_loc
=>
\&
_check_bug_file_loc
,
bug_file_loc
=>
\&
_check_bug_file_loc
,
bug_severity
=>
\&
_check_select_field
,
bug_severity
=>
\&
_check_select_field
,
bug_status
=>
\&
_check_bug_status
,
bug_status
=>
\&
_check_bug_status
,
...
@@ -132,6 +133,7 @@ sub VALIDATORS {
...
@@ -132,6 +133,7 @@ sub VALIDATORS {
component
=>
\&
_check_component
,
component
=>
\&
_check_component
,
creation_ts
=>
\&
_check_creation_ts
,
creation_ts
=>
\&
_check_creation_ts
,
deadline
=>
\&
_check_deadline
,
deadline
=>
\&
_check_deadline
,
dependson
=>
\&
_check_dependencies
,
dup_id
=>
\&
_check_dup_id
,
dup_id
=>
\&
_check_dup_id
,
estimated_time
=>
\&
_check_time_field
,
estimated_time
=>
\&
_check_time_field
,
everconfirmed
=>
\&
Bugzilla::Object::
check_boolean
,
everconfirmed
=>
\&
Bugzilla::Object::
check_boolean
,
...
@@ -187,14 +189,16 @@ sub VALIDATOR_DEPENDENCIES {
...
@@ -187,14 +189,16 @@ sub VALIDATOR_DEPENDENCIES {
my
%
deps
=
(
my
%
deps
=
(
assigned_to
=>
[
'component'
],
assigned_to
=>
[
'component'
],
blocked
=>
[
'product'
],
bug_status
=>
[
'product'
,
'comment'
,
'target_milestone'
],
bug_status
=>
[
'product'
,
'comment'
,
'target_milestone'
],
cc
=>
[
'component'
],
cc
=>
[
'component'
],
comment
=>
[
'creation_ts'
],
comment
=>
[
'creation_ts'
],
component
=>
[
'product'
],
component
=>
[
'product'
],
dependson
=>
[
'product'
],
dup_id
=>
[
'bug_status'
,
'resolution'
],
dup_id
=>
[
'bug_status'
,
'resolution'
],
groups
=>
[
'product'
],
groups
=>
[
'product'
],
keywords
=>
[
'product'
],
keywords
=>
[
'product'
],
resolution
=>
[
'bug_status'
],
resolution
=>
[
'bug_status'
,
'dependson'
],
qa_contact
=>
[
'component'
],
qa_contact
=>
[
'component'
],
target_milestone
=>
[
'product'
],
target_milestone
=>
[
'product'
],
version
=>
[
'product'
],
version
=>
[
'product'
],
...
@@ -749,12 +753,7 @@ sub run_create_validators {
...
@@ -749,12 +753,7 @@ sub run_create_validators {
$class
->
_check_strict_isolation
(
$params
->
{
cc
},
$params
->
{
assigned_to
},
$class
->
_check_strict_isolation
(
$params
->
{
cc
},
$params
->
{
assigned_to
},
$params
->
{
qa_contact
},
$product
);
$params
->
{
qa_contact
},
$product
);
(
$params
->
{
dependson
},
$params
->
{
blocked
})
=
# You can't set these fields.
$class
->
_check_dependencies
(
$params
->
{
dependson
},
$params
->
{
blocked
},
$product
);
# You can't set these fields on bug creation (or sometimes ever).
delete
$params
->
{
resolution
};
delete
$params
->
{
lastdiffed
};
delete
$params
->
{
lastdiffed
};
delete
$params
->
{
bug_id
};
delete
$params
->
{
bug_id
};
...
@@ -769,6 +768,11 @@ sub run_create_validators {
...
@@ -769,6 +768,11 @@ sub run_create_validators {
$params
);
$params
);
}
}
# And this is not a valid DB field, it's just used as part of
# _check_dependencies to avoid running it twice for both blocked
# and dependson.
delete
$params
->
{
_dependencies_validated
};
return
$params
;
return
$params
;
}
}
...
@@ -1370,9 +1374,9 @@ sub _check_bug_status {
...
@@ -1370,9 +1374,9 @@ sub _check_bug_status {
# Check if a comment is required for this change.
# Check if a comment is required for this change.
if
(
$new_status
->
comment_required_on_change_from
(
$old_status
)
&&
!
$comment
)
if
(
$new_status
->
comment_required_on_change_from
(
$old_status
)
&&
!
$comment
)
{
{
ThrowUserError
(
'comment_required'
,
{
old
=>
$old_status
,
ThrowUserError
(
'comment_required'
,
new
=>
$new_status
});
{
old
=>
$old_status
->
name
,
new
=>
$new_status
->
name
,
field
=>
'bug_status'
});
}
}
if
(
ref
$invocant
if
(
ref
$invocant
...
@@ -1453,7 +1457,24 @@ sub _check_comment {
...
@@ -1453,7 +1457,24 @@ sub _check_comment {
);
);
return
$comment
;
return
$comment
;
}
sub
_check_commenton
{
my
(
$invocant
,
$new_value
,
$field
,
$params
)
=
@_
;
my
$has_comment
=
ref
(
$invocant
)
?
$invocant
->
{
added_comments
}
:
(
defined
$params
->
{
comment
}
and
$params
->
{
comment
}
->
{
thetext
}
ne
''
);
my
$is_changing
=
ref
(
$invocant
)
?
$invocant
->
$field
ne
$new_value
:
$new_value
ne
''
;
if
(
$is_changing
&&
!
$has_comment
)
{
my
$old_value
=
ref
(
$invocant
)
?
$invocant
->
$field
:
undef
;
ThrowUserError
(
'comment_required'
,
{
field
=>
$field
,
old
=>
$old_value
,
new
=>
$new_value
});
}
}
}
sub
_check_component
{
sub
_check_component
{
...
@@ -1492,15 +1513,23 @@ sub _check_deadline {
...
@@ -1492,15 +1513,23 @@ sub _check_deadline {
# Takes two comma/space-separated strings and returns arrayrefs
# Takes two comma/space-separated strings and returns arrayrefs
# of valid bug IDs.
# of valid bug IDs.
sub
_check_dependencies
{
sub
_check_dependencies
{
my
(
$invocant
,
$depends_on
,
$blocks
,
$product
)
=
@_
;
my
(
$invocant
,
$value
,
$field
,
$params
)
=
@_
;
return
$value
if
$params
->
{
_dependencies_validated
};
if
(
!
ref
$invocant
)
{
if
(
!
ref
$invocant
)
{
# Only editbugs users can set dependencies on bug entry.
# Only editbugs users can set dependencies on bug entry.
return
(
[]
,
[]
)
unless
Bugzilla
->
user
->
in_group
(
'editbugs'
,
return
(
[]
,
[]
)
unless
Bugzilla
->
user
->
in_group
(
$product
->
id
);
'editbugs'
,
$params
->
{
product
}
->
id
);
}
}
my
%
deps_in
=
(
dependson
=>
$depends_on
||
''
,
blocked
=>
$blocks
||
''
);
# This is done this way so that dependson and blocked can be in
# VALIDATORS, meaning that they can be in VALIDATOR_DEPENDENCIES,
# which means that they can be checked in the right order during
# bug creation.
my
$opposite
=
$field
eq
'dependson'
?
'blocked'
:
'dependson'
;
my
%
deps_in
=
(
$field
=>
$value
||
''
,
$opposite
=>
$params
->
{
$opposite
}
||
''
);
foreach
my
$type
(
qw(dependson blocked)
)
{
foreach
my
$type
(
qw(dependson blocked)
)
{
my
@bug_ids
=
ref
(
$deps_in
{
$type
})
my
@bug_ids
=
ref
(
$deps_in
{
$type
})
...
@@ -1546,9 +1575,12 @@ sub _check_dependencies {
...
@@ -1546,9 +1575,12 @@ sub _check_dependencies {
# And finally, check for dependency loops.
# And finally, check for dependency loops.
my
$bug_id
=
ref
(
$invocant
)
?
$invocant
->
id
:
0
;
my
$bug_id
=
ref
(
$invocant
)
?
$invocant
->
id
:
0
;
my
%
deps
=
ValidateDependencies
(
$deps_in
{
dependson
},
$deps_in
{
blocked
},
$bug_id
);
my
%
deps
=
ValidateDependencies
(
$deps_in
{
dependson
},
$deps_in
{
blocked
},
$bug_id
);
return
(
$deps
{
'dependson'
},
$deps
{
'blocked'
});
$params
->
{
$opposite
}
=
$deps
{
$opposite
};
$params
->
{
_dependencies_validated
}
=
1
;
return
$deps
{
$field
};
}
}
sub
_check_dup_id
{
sub
_check_dup_id
{
...
@@ -1760,41 +1792,46 @@ sub _check_reporter {
...
@@ -1760,41 +1792,46 @@ sub _check_reporter {
}
}
sub
_check_resolution
{
sub
_check_resolution
{
my
(
$
self
,
$resolution
)
=
@_
;
my
(
$
invocant
,
$resolution
,
undef
,
$params
)
=
@_
;
$resolution
=
trim
(
$resolution
);
$resolution
=
trim
(
$resolution
);
my
$status
=
ref
(
$invocant
)
?
$invocant
->
status
->
name
:
$params
->
{
bug_status
};
my
$is_open
=
ref
(
$invocant
)
?
$invocant
->
status
->
is_open
:
is_open_state
(
$status
);
# Throw a special error for resolving bugs without a resolution
# Throw a special error for resolving bugs without a resolution
# (or trying to change the resolution to '' on a closed bug without
# (or trying to change the resolution to '' on a closed bug without
# using clear_resolution).
# using clear_resolution).
ThrowUserError
(
'missing_resolution'
,
{
status
=>
$s
elf
->
status
->
name
})
ThrowUserError
(
'missing_resolution'
,
{
status
=>
$s
tatus
})
if
!
$resolution
&&
!
$
self
->
status
->
is_open
;
if
!
$resolution
&&
!
$is_open
;
# Make sure this is a valid resolution.
# Make sure this is a valid resolution.
$resolution
=
$
self
->
_check_select_field
(
$resolution
,
'resolution'
);
$resolution
=
$
invocant
->
_check_select_field
(
$resolution
,
'resolution'
);
# Don't allow open bugs to have resolutions.
# Don't allow open bugs to have resolutions.
ThrowUserError
(
'resolution_not_allowed'
)
if
$
self
->
status
->
is_open
;
ThrowUserError
(
'resolution_not_allowed'
)
if
$is_open
;
# Check noresolveonopenblockers.
# Check noresolveonopenblockers.
my
$dependson
=
ref
(
$invocant
)
?
$invocant
->
dependson
:
(
$params
->
{
dependson
}
||
[]
);
if
(
Bugzilla
->
params
->
{
"noresolveonopenblockers"
}
if
(
Bugzilla
->
params
->
{
"noresolveonopenblockers"
}
&&
$resolution
eq
'FIXED'
&&
$resolution
eq
'FIXED'
&&
(
!
$self
->
resolution
||
$resolution
ne
$self
->
resolution
)
&&
(
!
ref
$invocant
or
!
$invocant
->
resolution
&&
scalar
@
{
$self
->
dependson
})
or
$resolution
ne
$invocant
->
resolution
)
&&
scalar
@$dependson
)
{
{
my
$dep_bugs
=
Bugzilla::
Bug
->
new_from_list
(
$
self
->
dependson
);
my
$dep_bugs
=
Bugzilla::
Bug
->
new_from_list
(
$dependson
);
my
$count_open
=
grep
{
$_
->
isopened
}
@$dep_bugs
;
my
$count_open
=
grep
{
$_
->
isopened
}
@$dep_bugs
;
if
(
$count_open
)
{
if
(
$count_open
)
{
my
$bug_id
=
ref
(
$invocant
)
?
$invocant
->
id
:
undef
;
ThrowUserError
(
"still_unresolved_bugs"
,
ThrowUserError
(
"still_unresolved_bugs"
,
{
bug_id
=>
$
self
->
id
,
dep_count
=>
$count_open
});
{
bug_id
=>
$
bug_
id
,
dep_count
=>
$count_open
});
}
}
}
}
# Check if they're changing the resolution and need to comment.
# Check if they're changing the resolution and need to comment.
if
(
Bugzilla
->
params
->
{
'commentonchange_resolution'
}
if
(
Bugzilla
->
params
->
{
'commentonchange_resolution'
})
{
&&
$self
->
resolution
&&
$resolution
ne
$self
->
resolution
$invocant
->
_check_commenton
(
$resolution
,
'resolution'
,
$params
);
&&
!
$self
->
{
added_comments
})
{
ThrowUserError
(
'comment_required'
);
}
}
return
$resolution
;
return
$resolution
;
...
@@ -2327,7 +2364,9 @@ sub set_custom_field {
...
@@ -2327,7 +2364,9 @@ sub set_custom_field {
sub
set_deadline
{
$_
[
0
]
->
set
(
'deadline'
,
$_
[
1
]);
}
sub
set_deadline
{
$_
[
0
]
->
set
(
'deadline'
,
$_
[
1
]);
}
sub
set_dependencies
{
sub
set_dependencies
{
my
(
$self
,
$dependson
,
$blocked
)
=
@_
;
my
(
$self
,
$dependson
,
$blocked
)
=
@_
;
(
$dependson
,
$blocked
)
=
$self
->
_check_dependencies
(
$dependson
,
$blocked
);
my
%
extra
=
(
blocked
=>
$blocked
);
$dependson
=
$self
->
_check_dependencies
(
$dependson
,
'dependson'
,
\%
extra
);
$blocked
=
$extra
{
blocked
};
# These may already be detainted, but all setters are supposed to
# These may already be detainted, but all setters are supposed to
# detaint their input if they've run a validator (just as though
# detaint their input if they've run a validator (just as though
# we had used Bugzilla::Object::set), so we do that here.
# we had used Bugzilla::Object::set), so we do that here.
...
@@ -3854,6 +3893,8 @@ sub map_fields {
...
@@ -3854,6 +3893,8 @@ sub map_fields {
my
%
field_values
;
my
%
field_values
;
foreach
my
$field
(
keys
%
$params
)
{
foreach
my
$field
(
keys
%
$params
)
{
# Don't allow setting private fields via email_in or the WebService.
next
if
$field
=~
/^_/
;
my
$field_name
;
my
$field_name
;
if
(
$except
->
{
$field
})
{
if
(
$except
->
{
$field
})
{
$field_name
=
$field
;
$field_name
=
$field
;
...
...
Bugzilla/WebService/Bug.pm
View file @
89cf83ec
...
@@ -2288,6 +2288,11 @@ the component's default QA Contact.
...
@@ -2288,6 +2288,11 @@ the component's default QA Contact.
=item C<status> (string) - The status that this bug should start out as.
=item C<status> (string) - The status that this bug should start out as.
Note that only certain statuses can be set on bug creation.
Note that only certain statuses can be set on bug creation.
=item C<resolution> (string) - If you are filing a closed bug, then
you will have to specify a resolution. You cannot currently specify
a resolution of C<DUPLICATE> for new bugs, though. That must be done
with L</update>.
=item C<target_milestone> (string) - A valid target milestone for this
=item C<target_milestone> (string) - A valid target milestone for this
product.
product.
...
@@ -2370,6 +2375,9 @@ argument.
...
@@ -2370,6 +2375,9 @@ argument.
=item Error 116 was added in Bugzilla B<4.0>. Before that, dependency
=item Error 116 was added in Bugzilla B<4.0>. Before that, dependency
loop errors had a generic code of C<32000>.
loop errors had a generic code of C<32000>.
=item The ability to file new bugs with a C<resolution> was added in
Bugzilla B<4.2>.
=back
=back
=back
=back
...
...
editworkflow.cgi
View file @
89cf83ec
...
@@ -87,7 +87,7 @@ elsif ($action eq 'update') {
...
@@ -87,7 +87,7 @@ elsif ($action eq 'update') {
# Part 1: Initial bug statuses.
# Part 1: Initial bug statuses.
foreach
my
$new
(
@$statuses
)
{
foreach
my
$new
(
@$statuses
)
{
if
(
$
new
->
is_open
&&
$
cgi
->
param
(
'w_0_'
.
$new
->
id
))
{
if
(
$cgi
->
param
(
'w_0_'
.
$new
->
id
))
{
$sth_insert
->
execute
(
undef
,
$new
->
id
)
$sth_insert
->
execute
(
undef
,
$new
->
id
)
unless
defined
$workflow
->
{
0
}
->
{
$new
->
id
};
unless
defined
$workflow
->
{
0
}
->
{
$new
->
id
};
}
}
...
...
template/en/default/admin/workflow/edit.html.tmpl
View file @
89cf83ec
...
@@ -68,7 +68,7 @@
...
@@ -68,7 +68,7 @@
</th>
</th>
[% FOREACH new_status = statuses %]
[% FOREACH new_status = statuses %]
[% IF status.id != new_status.id
&& (status.id || new_status.is_open)
%]
[% IF status.id != new_status.id %]
[% checked = workflow.${status.id}.${new_status.id}.defined ? 1 : 0 %]
[% checked = workflow.${status.id}.${new_status.id}.defined ? 1 : 0 %]
[% mandatory = (status.id && new_status.name == Param("duplicate_or_move_bug_status")) ? 1 : 0 %]
[% mandatory = (status.id && new_status.name == Param("duplicate_or_move_bug_status")) ? 1 : 0 %]
<td align="center" class="checkbox-cell[% " checked" IF checked || mandatory %]"
<td align="center" class="checkbox-cell[% " checked" IF checked || mandatory %]"
...
...
template/en/default/global/user-error.html.tmpl
View file @
89cf83ec
...
@@ -308,9 +308,10 @@
...
@@ -308,9 +308,10 @@
[% ELSIF error == "comment_required" %]
[% ELSIF error == "comment_required" %]
[% title = "Comment Required" %]
[% title = "Comment Required" %]
You have to specify a
You have to specify a
[% IF old && new %]
[% IF old.defined && new.defined %]
<b>comment</b> when changing the status of [% terms.abug %] from
<b>comment</b> when changing the [% field_descs.$field FILTER html %]
[%+ old.name FILTER html %] to [% new.name FILTER html %].
of [% terms.abug %] from [% (old || "(empty)") FILTER html %]
to [% (new || "(empty)") FILTER html %].
[% ELSIF new %]
[% ELSIF new %]
description for this [% terms.bug %].
description for this [% terms.bug %].
[% ELSE %]
[% ELSE %]
...
@@ -1527,7 +1528,11 @@
...
@@ -1527,7 +1528,11 @@
[% ELSIF error == "still_unresolved_bugs" %]
[% ELSIF error == "still_unresolved_bugs" %]
[% title = "Unresolved Dependencies" %]
[% title = "Unresolved Dependencies" %]
[% IF bug_id %]
[% terms.Bug %] [%+ bug_id FILTER bug_link(bug_id) FILTER none %]
[% terms.Bug %] [%+ bug_id FILTER bug_link(bug_id) FILTER none %]
[% ELSE %]
This [% terms.bug %]
[% END %]
has [% dep_count FILTER none %] unresolved
has [% dep_count FILTER none %] unresolved
[% IF dep_count == 1 %]
[% IF dep_count == 1 %]
dependency
dependency
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment