[Rt-devel] [PATCH]: Check Select* CF fields for valid values in
ticket REST interface
Philip Kime
pkime at Shopzilla.com
Sun Dec 24 13:16:22 EST 2006
This patch to <rt path>/share/html/REST/1.0/Forms/ticket/default checks
Select* fields for valid values and won't set them if the value isn't
valid. Works for multiple fields too. This has to be enforced in the
REST code - it's enforced in the GUI simply by the semantics of select
boxes.
Patch should be valid against 3.6.x
--- /tmp/rt-3.6.3/html/REST/1.0/Forms/ticket/default 2006-09-26
08:06:31.000000000 -0700
+++ /usr/local/rt/share/html/REST/1.0/Forms/ticket/default
2006-12-24 09:58:22.553405248 -0800
@@ -128,18 +128,6 @@
if (exists $create{lc $k}) {
$v{$create{lc $k}} = delete $data{$k};
}
- # Set custom field
- elsif ($k =~ /^CF-/i) {
- my $cf = RT::CustomField->new( $RT::SystemUser );
- my $cfk = $k;
- $cfk =~ s/^CF-//i;
- unless($cf->LoadByName( Name => $cfk )) {
- push @comments, "# Invalid custom field name
($cfk)";
- delete $data{$k};
- next;
- }
- $v{"CustomField-".$cf->Id()} = delete $data{$k};
- }
elsif (lc $k eq 'text') {
$text = delete $data{$k};
}
@@ -157,6 +145,8 @@
);
}
+ # Don't add custom fields here - let it fall through to check
them later
+ # This creates a seperate transaction but that's ok
$ticket->Create(%v);
unless ($ticket->Id) {
return [ "# Could not create ticket.", [], {}, 1 ];
@@ -229,7 +219,7 @@
foreach $key (keys %data) {
$val = $data{$key};
$key = lc $key;
- $n = 1;
+ # $n = 1;
if (ref $val eq 'ARRAY') {
unless ($key =~ /^(?:Requestors|Cc|AdminCc)$/i) {
@@ -302,17 +292,131 @@
}
# Set custom field
elsif ($key =~ /^CF-/i) {
- my $cf = RT::CustomField->new( $RT::SystemUser );
+ my @msgs;
+ my $CustomFieldObj = RT::CustomField->new( $RT::SystemUser
);
$key =~ s/^CF-//i;
- if (not $cf->LoadByName( Name => $key )) {
- $n = 0;
- $s = "Unknown custom field.";
- }
- else {
- ($n, $s) = $ticket->AddCustomFieldValue(
- Field => $cf, Value => $val );
- $s =~ s/^# // if defined $s;
- }
+
+ my ($r, $rmsg) = (undef, undef);
+ $CustomFieldObj->LoadByName( Name => $key );
+ unless ($CustomFieldObj->Id) {
+ $s = 0;
+ $n = "Could not load Custom Field \"$key\" - does it
exist?";
+ push @msgs, [ $s, $n ];
+ goto CFEND;
+ }
+
+ if
($CustomFieldObj->CurrentUserHasRight('ModifyCustomField')) {
+
+ # Don't change any field that hasn't changed - otherwise
the Asset History shows
+ # that every field changes on changing any field.
+ my $CFvalues = $ticket->CustomFieldValues($key);
+
+ goto CFEND unless ($CFvalues->Count || length($val)); # If
new and old are both empty, do nothing
+
+ # Single-Valued Field
+ if ($CustomFieldObj->SingleValue) {
+
+ # First check for valid value for Select fields,
as long as value isn't null (this is just a delete)
+ if (($CustomFieldObj->Type eq "Select") &&
length($val)) {
+ my $ValidVals = $CustomFieldObj->Values;
+ my $valok = 0;
+ while (my $vv = $ValidVals->Next()) {
+ if ($vv->Name eq $val) {
+ $valok = 1;
+ last;
+ }
+ }
+ if (!$valok) { # Stop processing this Custom
field if it's not a valid value.
+ $s = 0;
+ $n = "$val is not a valid Value for Ticket Custom
Field $key";
+ push @msgs, [ $s, $n ];
+ goto CFEND;
+ }
+ }
+ if ((my $CFvalue = $CFvalues->Next()) ||
length($val) ) {
+ # Skip delete unless we're going
from a value to nothing (changing a value doesn't need a delete first)
+ goto SVCFADD unless ((defined
$CFvalue) && (! length($val)));
+ goto CFEND if ($CFvalue->Content
eq $val); # Skip delete and add if there is nothing to do
+ unless ($ticket->DeleteCustomFieldValue(Field =>
$CustomFieldObj, Value => $CFvalue->Content)) {
+ $s = 0;
+ $n = "Could not delete Ticket Custom Field Value
".$CFvalue->Content." for Field $key";
+ push @msgs, [ $s, $n ];
+ }
+SVCFADD:
+ goto CFEND unless length($val);
+ unless ($ticket->AddCustomFieldValue(Field =>
$CustomFieldObj, Value => $val)) {
+ $s = 0;
+ $n = "Could not add value $val to Ticket Custom
Field $key";
+ push @msgs, [ $s, $n ];
+ }
+ }
+ }
+ # Multi-Valued Field
+ elsif (! $CustomFieldObj->SingleValue) {
+ my @val = @ { vsplit($val) };
+
+ # First check for valid value for Select
fields, as long as value isn't null (this is just a delete)
+ if ($CustomFieldObj->Type eq "Select") {
+ my @ValidVals =
@{$CustomFieldObj->Values->ItemsArrayRef};
+ my $valok;
+ foreach my $pv (@val) {
+ $valok = 0;
+ foreach my $vv (@ValidVals) {
+ if ($vv->Name eq $pv) {
+ $valok = 1;
+ last;
+ }
+ }
+ if (!$valok) { # Stop processing this Custom
field if it's not a valid value.
+ $s = 0;
+ $n = "$pv is not a valid Value for Ticket Custom
Field $key";
+ push @msgs, [ $s, $n ];
+ goto CFEND;
+ }
+ }
+ }
+
+ my @CFVALS = map {$_->Content}
@{$CFvalues->ItemsArrayRef};
+ my $CFvalue;
+ my $mv;
+ # Process additions
+ foreach my $newval (@val) {
+ if (! grep {$newval eq $_} @CFVALS ) {
+ unless
($ticket->AddCustomFieldValue(Field => $CustomFieldObj, Value =>
$newval)) {
+ $s = 0;
+ $n = "Could not add Ticket Custom Field Value
$newval to Ticket Custom Field $key";
+ push @msgs, [ $s, $n ];
+ }
+ }
+ }
+ # Process deletions
+ foreach my $oldval (@CFVALS) {
+ if (! grep {$oldval eq $_} @val ) {
+ unless
($ticket->DeleteCustomFieldValue(Field => $CustomFieldObj, Value =>
$oldval)) {
+ $s = 0;
+ $n = "Could not delete Ticket Custom Field Value
$oldval to Ticket Custom Field $key";
+ push @msgs, [ $s, $n ];
+ }
+ }
+ }
+ }
+ }
+ else {
+ $n = 0;
+ $s = "You do not have permission to modify these custom
fields";
+ }
+
+
+CFEND:
+ # collate all error messages from the above transactions into
one string
+ $n = 1;
+ if (@msgs = grep {$_->[0] == 0} @msgs) {
+ $n = 0;
+ $s = join "\n", map {"# ".$_->[1]} @msgs;
+ $s =~ s/^# //;
+ }
+
+
}
elsif ($key ne 'id' && $key ne 'type' && $key ne 'creator') {
$n = 0;
More information about the Rt-devel
mailing list