[rt-devel] How to add custom field
Matthew D. Stock
stock at cse.Buffalo.EDU
Tue Mar 30 08:38:23 EST 2004
Kuldeep Singh Tomar writes:
> How can we add the value of custom field on submission of mail. I am
> using rt3. Basically we are using some interface where we submit the
> mail to rt-system and want to use the value of custom fields in our
> rtsystem through this interface.
Assuming you mean assign custom field values to tickets and not create new
custom field values...
Here's a patch for 3.0.9 that adds the ability to parse X- headers in
email. It currently only uses MailFrom authentication. It will process
several field types, most notably Select custom fields. Read the patch for
details on use, but here are a couple of examples:
X-owner: stock
X-status: resolved
X-customfoobar: flammable
Jesse, are you interested in taking this as part of 3.0.x or as a contrib?
-Matt
--
Matthew D. Stock <stock at cse.buffalo.edu>
Director of Information Technology
Computer Science and Engineering, University at Buffalo
-------------- next part --------------
diff -ur rt-3-0-9/lib/RT/Interface/Email/Auth/MailFrom.pm rt3/lib/RT/Interface/Email/Auth/MailFrom.pm
--- rt-3-0-9/lib/RT/Interface/Email/Auth/MailFrom.pm Fri Feb 13 12:31:23 2004
+++ rt3/lib/RT/Interface/Email/Auth/MailFrom.pm Thu Mar 11 15:45:25 2004
@@ -45,7 +45,17 @@
}
if ( $CurrentUser->Id ) {
+ my $Queue;
+
+ if (defined($Queue = $args{'Queue'}) &&
+ $Queue->IsWatcher(Type => 'AdminCC',
+ PrincipalId => $CurrentUser->PrincipalId)) {
+ $RT::Logger->debug( "Giving elevated privs" );
+ return ( $CurrentUser, 2);
+ } else {
+ $RT::Logger->debug( "Normal privs" );
return ( $CurrentUser, 1 );
+ }
}
diff -ur rt-3-0-9/lib/RT/Interface/Email.pm rt3/lib/RT/Interface/Email.pm
--- rt-3-0-9/lib/RT/Interface/Email.pm Fri Feb 13 12:31:23 2004
+++ rt3/lib/RT/Interface/Email.pm Fri Mar 12 14:45:51 2004
@@ -331,6 +331,56 @@
}
# }}}
+# {{{ ParseActionsFromHead
+
+=head2 ParseActionsFromHead RT::Queue MIME::Header
+
+Return an array of action value pairs. These pairs should be vetted here,
+since they will be passed on to the Ticket methods.
+
+=cut
+
+sub ParseActionsFromHead {
+ my $QueueObj = shift;
+ my $head = shift;
+ my @actions = ();
+
+ # If we were asked about the status, check to see if it's valid for that
+ # queue. If not, silently ignore the field.
+ if (my $headerobj = $head->get('X-Status')) {
+ chomp($headerobj);
+ if ($QueueObj->IsValidStatus($headerobj)) {
+ push @actions, 'Status', $headerobj;
+ }
+ }
+
+ # We'll let the ticket code check to make sure it's ok to set the owner.
+ if (my $headerobj = $head->get('X-Owner')) {
+ chomp($headerobj);
+ push @actions, 'Owner', $headerobj;
+ }
+
+ if (my $headerobj = $head->get('X-TimeTaken')) {
+ chomp($headerobj);
+ push @actions, 'TimeTaken', $headerobj;
+ }
+
+ # Sort out the custom field tags for this queue. We don't have a ticket
+ # yet, so the tests on the values happens later.
+ my $CustomFields = $QueueObj->CustomFields();
+ while (my $CustomField = $CustomFields->Next()) {
+ my $i=0;
+ foreach my $headerobj ($head->get('X-'.$CustomField->Name)) {
+ chomp($headerobj);
+ $RT::Logger->debug("Found customfield $i " . $CustomField->Name);
+ push @actions, $CustomField->Name . "-$i", $headerobj;
+ $i++;
+ }
+ }
+ return @actions;
+}
+# }}}
+
# {{{ ParseAddressFromHeader
=head2 ParseAddressFromHeader ADDRESS
@@ -361,6 +411,70 @@
# }}}
+sub ProcessActions {
+ my $CurrentUser = shift;
+ my $Ticket = shift;
+ my %actions = @_;
+ my %seen;
+ my $CustomFields = $Ticket->QueueObj->CustomFields();
+
+ foreach my $action (keys %actions) {
+ $RT::Logger->debug("Found an $action action");
+ if ($action eq 'Owner') {
+ chomp($actions{$action});
+ $RT::Logger->debug("Setting new owner to " . $actions{$action});
+ my ($success, $msg) = $Ticket->SetOwner($actions{$action}, "Force");
+ if (!$success) {
+ $RT::Logger->debug("SetOwner(): $msg");
+ }
+ }
+
+ if ($action eq 'Status' && $Ticket->Status != $actions{$action}) {
+ $Ticket->SetStatus($actions{$action});
+ }
+
+ my ($cfield, $index) = split('-',$action);
+ while (my $CustomField = $CustomFields->Next) {
+ my $name = $CustomField->Name;
+
+ next if ($cfield ne $name);
+ next if ($CustomField->Type !~ /^Select/);
+
+ # Now that we have a custom field match, we need to make sure the
+ # value is valid. This is complicated because of the various kinds
+ # of fields. For the moment, I'm only going to deal with Select
+ # fields, since that's all we use.
+ #
+ # We also assume that if ANY value of a multivalue custom field is
+ # offered, that the complete set will be provided. In other words, we
+ # empty out the values for that field, and set only the ones that
+ # are in the headers.
+ chomp($actions{$action});
+ my $CustomFieldValues = $CustomField->Values();
+
+ # If we have index 0, nuke all of the existing values.
+ if ($CustomField->Type eq "SelectMultiple" &&
+ !defined($seen{$CustomField->Name})) {
+ $seen{$CustomField->Name} = 1;
+ $RT::Logger->debug("Starting Delete loop");
+ while (my $value = $CustomFieldValues->Next) {
+ my ($status, $msg) =
+ $Ticket->DeleteCustomFieldValue(Field => $CustomField->Id,
+ Value => $value->Name);
+ }
+ }
+
+ while (my $value = $CustomFieldValues->Next) {
+ # Case insensitive match, to be friendly to the user.
+ next if (lc($value->Name) ne lc($actions{$action}));
+ my ($status, $msg) =
+ $Ticket->AddCustomFieldValue(Field => $CustomField->Id,
+ Value => $value->Name);
+ last;
+ }
+ }
+ }
+}
=head2 Gateway ARGSREF
@@ -503,6 +617,7 @@
for (@RT::MailPlugins) {
my $Code;
my $NewAuthStat;
+
if ( ref($_) eq "CODE" ) {
$Code = $_;
}
@@ -607,6 +722,17 @@
}
# }}}
+
+ # {{{ If the user has enough privs, process action headers.
+
+ my @actions = ();
+ if ( $AuthStat == 2 ) {
+ $RT::Logger->debug("We have the privs to look for actions!");
+ @actions = ParseActionsFromHead($SystemQueueObj, $head);
+ }
+
+ # }}}
+
# {{{ Warn someone if it's a loop
# Warn someone if it's a loop, before we drop it on the ground
@@ -663,7 +789,7 @@
@Cc = ParseCcAddressesFromHead(
Head => $head,
CurrentUser => $CurrentUser,
- QueueObj => $SystemQueueObj
+ QueueObj => $SystemQueueObj
);
}
@@ -672,7 +798,8 @@
Subject => $Subject,
Requestor => \@Requestors,
Cc => \@Cc,
- MIMEObj => $Message
+ MIMEObj => $Message,
+ @actions
);
if ( $id == 0 ) {
MailError(
@@ -706,11 +833,14 @@
}
my ( $status, $msg );
+ ProcessActions($CurrentUser, $Ticket, @actions);
if ( $args{'action'} =~ /^correspond$/ ) {
- ( $status, $msg ) = $Ticket->Correspond( MIMEObj => $Message );
+ ( $status, $msg ) = $Ticket->Correspond( MIMEObj => $Message,
+ @actions);
}
else {
- ( $status, $msg ) = $Ticket->Comment( MIMEObj => $Message );
+ ( $status, $msg ) = $Ticket->Comment( MIMEObj => $Message,
+ @actions);
}
unless ($status) {
More information about the Rt-devel
mailing list