import rt 3.4.6
[freeside.git] / rt / lib / RT / Interface / Web.pm
index 724d7e5..8bc840b 100644 (file)
@@ -288,9 +288,18 @@ sub CreateTicket {
         Body                => $ARGS{'Content'},
     );
 
-    if ($ARGS{'Attachments'}) {
-        $MIMEObj->make_multipart;
-        $MIMEObj->add_part($_) foreach values %{$ARGS{'Attachments'}};
+    if ( $ARGS{'Attachments'} ) {
+        my $rv = $MIMEObj->make_multipart;
+        $RT::Logger->error("Couldn't make multipart message")
+            if !$rv || $rv !~ /^(?:DONE|ALREADY)$/;
+
+        foreach ( values %{$ARGS{'Attachments'}} ) {
+            unless ( $_ ) {
+                $RT::Logger->error("Couldn't add empty attachemnt");
+                next;
+            }
+            $MIMEObj->add_part($_);
+        }
     }
 
     my %create_args = (
@@ -1132,161 +1141,174 @@ sub ProcessObjectCustomFieldUpdates {
     # Build up a list of objects that we want to work with
     my %custom_fields_to_mod;
     foreach my $arg ( keys %$ARGSRef ) {
-        if ( $arg =~ /^Object-([\w:]+)-(\d*)-CustomField-(\d+)-/ ) {
-            # For each of those objects, find out what custom fields we want to work with.
-            $custom_fields_to_mod{$1}{$2 || $args{'Object'}->Id}{$3} = 1;
-        }
+        # format: Object-<object class>-<object id>-CustomField-<CF id>-<commands>
+        next unless $arg =~ /^Object-([\w:]+)-(\d*)-CustomField-(\d+)-(.*)$/;
+
+        # For each of those objects, find out what custom fields we want to work with.
+        $custom_fields_to_mod{ $1 }{ $2 || 0 }{ $3 }{ $4 } = $ARGSRef->{ $arg };
     }
 
     # For each of those objects
     foreach my $class ( keys %custom_fields_to_mod ) {
-       foreach my $id ( keys %{$custom_fields_to_mod{$class}} ) {
-           my $Object = $args{'Object'};
-           if (!$Object or ref($Object) ne $class or $Object->id != $id) {
-               $Object = $class->new( $session{'CurrentUser'} );
-               $Object->Load($id);
-       }
+        foreach my $id ( keys %{$custom_fields_to_mod{$class}} ) {
+            my $Object = $args{'Object'};
+            $Object = $class->new( $session{'CurrentUser'} )
+                unless $Object && ref $Object eq $class;
+
+            $Object->Load( $id ) unless ($Object->id || 0) == $id;
+            unless ( $Object->id ) {
+                $RT::Logger->warning("Couldn't load object $class #$id");
+                next;
+            }
 
-           # For each custom field  
-           foreach my $cf ( keys %{ $custom_fields_to_mod{$class}{$id} } ) {
-           my $CustomFieldObj = RT::CustomField->new($session{'CurrentUser'});
-           $CustomFieldObj->LoadById($cf);
-
-               foreach my $arg ( keys %{$ARGSRef} ) {
-                   # Only interested in args for the current CF:
-                   next unless ( $arg =~ /^Object-$class-(?:$id)?-CustomField-$cf-/ );
-
-                   # since http won't pass in a form element with a null value, we need
-                   # to fake it
-                   if ($arg =~ /^(.*?)-Values-Magic$/ ) {
-                       # We don't care about the magic, if there's really a values element;
-                       next if ($ARGSRef->{$1.'-Value'} || $ARGSRef->{$1.'-Values'}) ;
-
-                        # "Empty" values does not mean anything for Image and Binary fields
-                        next if $CustomFieldObj->Type =~ /^(?:Image|Binary)$/;
-
-                       $arg = $1."-Values";
-                       $ARGSRef->{$1."-Values"} = undef;
-                   
-                   }
-                   my @values = ();
-                   if (ref( $ARGSRef->{$arg} ) eq 'ARRAY' ) {
-                       @values = @{ $ARGSRef->{$arg} };
-                   } elsif ($CustomFieldObj->Type =~ /text/i) { # Both Text and Wikitext
-                       @values = ($ARGSRef->{$arg});
-                   } else {
-                       @values = split /\n/, $ARGSRef->{$arg};
-                   }
-                   
-                   if ( ($CustomFieldObj->Type eq 'Freeform' 
-                         && ! $CustomFieldObj->SingleValue) ||
-                         $CustomFieldObj->Type =~ /text/i) {
-                       foreach my $val (@values) {
-                           $val =~ s/\r//g;
-                       }
-                   }
-
-                   if ( ( $arg =~ /-AddValue$/ ) || ( $arg =~ /-Value$/ ) ) {
-                       foreach my $value (@values) {
-                           next unless length($value);
-                           my ( $val, $msg ) = $Object->AddCustomFieldValue(
-                               Field => $cf,
-                               Value => $value
-                           );
-                           push ( @results, $msg );
-                       }
-                   }
-                   elsif ( $arg =~ /-Upload$/ ) {
-                        my $value_hash = _UploadedFile($arg) or next;
-
-                       my ( $val, $msg ) = $Object->AddCustomFieldValue(
-                            %$value_hash,
-                            Field => $cf,
-                       );
-                       push ( @results, $msg );
-                   }
-                   elsif ( $arg =~ /-DeleteValues$/ ) {
-                       foreach my $value (@values) {
-                           next unless length($value);
-                           my ( $val, $msg ) = $Object->DeleteCustomFieldValue(
-                               Field => $cf,
-                               Value => $value
-                           );
-                           push ( @results, $msg );
-                       }
-                   }
-                   elsif ( $arg =~ /-DeleteValueIds$/ ) {
-                       foreach my $value (@values) {
-                           next unless length($value);
-                           my ( $val, $msg ) = $Object->DeleteCustomFieldValue(
-                               Field => $cf,
-                               ValueId => $value,
-                           );
-                           push ( @results, $msg );
-                       }
-                   }
-                   elsif ( $arg =~ /-Values$/ and !$CustomFieldObj->Repeated) {
-                       my $cf_values = $Object->CustomFieldValues($cf);
-
-                       my %values_hash;
-                       foreach my $value (@values) {
-                           next unless length($value);
-
-                           # build up a hash of values that the new set has
-                           $values_hash{$value} = 1;
-
-                           unless ( $cf_values->HasEntry($value) ) {
-                               my ( $val, $msg ) = $Object->AddCustomFieldValue(
-                                   Field => $cf,
-                                   Value => $value
-                               );
-                               push ( @results, $msg );
-                           }
-
-                       }
-                       while ( my $cf_value = $cf_values->Next ) {
-                           unless ( $values_hash{ $cf_value->Content } == 1 ) {
-                               my ( $val, $msg ) = $Object->DeleteCustomFieldValue(
-                                   Field => $cf,
-                                   Value => $cf_value->Content
-                               );
-                               push ( @results, $msg);
-
-                           }
-                       }
-                   }
-                   elsif ( $arg =~ /-Values$/ ) {
-                       my $cf_values = $Object->CustomFieldValues($cf);
-
-                   # keep everything up to the point of difference, delete the rest
-                   my $delete_flag;
-                   foreach my $old_cf (@{$cf_values->ItemsArrayRef}) {
-                       if (!$delete_flag and @values and $old_cf->Content eq $values[0]) {
-                           shift @values;
-                           next;
-                       }
-
-                       $delete_flag ||= 1;
-                       $old_cf->Delete;
-                   }
-
-                   # now add/replace extra things, if any
-                   foreach my $value (@values) {
-                           my ( $val, $msg ) = $Object->AddCustomFieldValue(
-                           Field => $cf,
-                           Value => $value
-                       );
-                       push ( @results, $msg );
-                   }
-               }
-                   else {
-                       push ( @results, loc("User asked for an unknown update type for custom field [_1] for [_2] object #[_3]", $cf->Name, $class, $Object->id ) );
-                   }
-               }
-           }
-           return (@results);
-       }
+            foreach my $cf ( keys %{ $custom_fields_to_mod{ $class }{ $id } } ) {
+                my $CustomFieldObj = RT::CustomField->new( $session{'CurrentUser'} );
+                $CustomFieldObj->LoadById( $cf );
+                unless ( $CustomFieldObj->id ) {
+                    $RT::Logger->warning("Couldn't load custom field #$id");
+                    next;
+                }
+                push @results, _ProcessObjectCustomFieldUpdates(
+                    Prefix      => "Object-$class-$id-CustomField-$cf-",
+                    Object      => $Object,
+                    CustomField => $CustomFieldObj,
+                    ARGS        => $custom_fields_to_mod{$class}{$id}{$cf},
+                );
+            }
+        }
+    }
+    return @results;
+}
+
+sub _ProcessObjectCustomFieldUpdates {
+    my %args = @_;
+    my $cf = $args{'CustomField'};
+    my $cf_type = $cf->Type;
+
+    my @results;
+    foreach my $arg ( keys %{ $args{'ARGS'} } ) {
+
+        # since http won't pass in a form element with a null value, we need
+        # to fake it
+        if ( $arg eq 'Values-Magic' ) {
+            # We don't care about the magic, if there's really a values element;
+            next if $args{'ARGS'}->{'Value'} || $args{'ARGS'}->{'Values'};
+
+            # "Empty" values does not mean anything for Image and Binary fields
+            next if $cf_type =~ /^(?:Image|Binary)$/;
+
+            $arg = 'Values';
+            $args{'ARGS'}->{'Values'} = undef;
+        }
+
+        my @values = ();
+        if ( ref $args{'ARGS'}->{ $arg } eq 'ARRAY' ) {
+            @values = @{ $args{'ARGS'}->{$arg} };
+        } elsif ( $cf_type =~ /text/i ) { # Both Text and Wikitext
+            @values = ($args{'ARGS'}->{$arg});
+        } else {
+            @values = split /\n/, $args{'ARGS'}->{ $arg };
+        }
+        
+        if ( ( $cf_type eq 'Freeform' && !$cf->SingleValue ) || $cf_type =~ /text/i ) {
+            s/\r//g foreach @values;
+        }
+        @values = grep defined && $_ ne '', @values;
+
+        if ( $arg eq 'AddValue' || $arg eq 'Value' ) {
+            foreach my $value (@values) {
+                my ( $val, $msg ) = $args{'Object'}->AddCustomFieldValue(
+                    Field => $cf->id,
+                    Value => $value
+                );
+                push ( @results, $msg );
+            }
+        }
+        elsif ( $arg eq 'Upload' ) {
+            my $value_hash = _UploadedFile( $args{'Prefix'} . $arg ) or next;
+            my ( $val, $msg ) = $args{'Object'}->AddCustomFieldValue(
+                %$value_hash,
+                Field => $cf,
+            );
+            push ( @results, $msg );
+        }
+        elsif ( $arg eq 'DeleteValues' ) {
+            foreach my $value ( @values ) {
+                my ( $val, $msg ) = $args{'Object'}->DeleteCustomFieldValue(
+                    Field => $cf,
+                    Value => $value,
+                );
+                push ( @results, $msg );
+            }
+        }
+        elsif ( $arg eq 'DeleteValueIds' ) {
+            foreach my $value ( @values ) {
+                my ( $val, $msg ) = $args{'Object'}->DeleteCustomFieldValue(
+                    Field   => $cf,
+                    ValueId => $value,
+                );
+                push ( @results, $msg );
+            }
+        }
+        elsif ( $arg eq 'Values' && !$cf->Repeated ) {
+            my $cf_values = $args{'Object'}->CustomFieldValues( $cf->id );
+
+            my %values_hash;
+            foreach my $value ( @values ) {
+                # build up a hash of values that the new set has
+                $values_hash{$value} = 1;
+                next if $cf_values->HasEntry( $value );
+
+                my ( $val, $msg ) = $args{'Object'}->AddCustomFieldValue(
+                    Field => $cf,
+                    Value => $value
+                );
+                push ( @results, $msg );
+            }
+
+            $cf_values->RedoSearch;
+            while ( my $cf_value = $cf_values->Next ) {
+                next if $values_hash{ $cf_value->Content };
+
+                my ( $val, $msg ) = $args{'Object'}->DeleteCustomFieldValue(
+                    Field => $cf,
+                    Value => $cf_value->Content
+                );
+                push ( @results, $msg);
+            }
+        }
+        elsif ( $arg eq 'Values' ) {
+            my $cf_values = $args{'Object'}->CustomFieldValues( $cf->id );
+
+            # keep everything up to the point of difference, delete the rest
+            my $delete_flag;
+            foreach my $old_cf (@{$cf_values->ItemsArrayRef}) {
+                if (!$delete_flag and @values and $old_cf->Content eq $values[0]) {
+                    shift @values;
+                    next;
+                }
+
+                $delete_flag ||= 1;
+                $old_cf->Delete;
+            }
+
+            # now add/replace extra things, if any
+            foreach my $value ( @values ) {
+                my ( $val, $msg ) = $args{'Object'}->AddCustomFieldValue(
+                    Field => $cf,
+                    Value => $value
+                );
+                push ( @results, $msg );
+            }
+        }
+        else {
+            push ( @results, loc("User asked for an unknown update type"
+                ." for custom field [_1] for [_2] object #[_3]",
+                $cf->Name, ref $args{'Object'}, $args{'Object'}->id )
+            );
+        }
     }
+    return @results;
 }
 
 # {{{ sub ProcessTicketWatchers