[rt-devel] How to add custom field

Kuldeep Singh Tomar tomar at vcustomer.com
Tue Mar 30 09:23:24 EST 2004


Hi Matthew,

Yes, you are right. I need to display the value of custom field in web 
interface given by mail or better to say parse it.
Thanks a lot for your answer and patch, I am looking into it and get 
back to you soon.

Thanks again.

Kuldeep

Matthew D. Stock wrote:

>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
>
>  
>
>------------------------------------------------------------------------
>
>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