X-Git-Url: http://git.freeside.biz/gitweb/?a=blobdiff_plain;f=rt%2Flib%2FRT%2FInterface%2FWeb.pm;h=409cbdc4591ef241f05cafef2d2b0dfdedf0f7e4;hb=9ecdd3410e3b41791e4d444a9c29157b5dbbe2bb;hp=4a6bfda88e52a87db3301cc3f6ce9983022e06c7;hpb=35e5b12fb55f229edd16bed66e21c5806b8d3b7e;p=freeside.git diff --git a/rt/lib/RT/Interface/Web.pm b/rt/lib/RT/Interface/Web.pm index 4a6bfda88..409cbdc45 100644 --- a/rt/lib/RT/Interface/Web.pm +++ b/rt/lib/RT/Interface/Web.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) @@ -1246,6 +1246,10 @@ sub ValidateWebConfig { ."otherwise your internal links may be broken."); } + return; #next warning flooding our logs, doesn't seem applicable to our use + # (SCRIPT_NAME is the full path, WebPath is just the beginning) + #in vanilla RT does something eat the local part of SCRIPT_NAME 1st? + # Unfortunately, there is no reliable way to get the _path_ that was # requested at the proxy level; simply disable this warning if we're # proxied and there's a mismatch. @@ -1283,10 +1287,16 @@ our %is_whitelisted_component = ( # While these can be used for denial-of-service against RT # (construct a very inefficient query and trick lots of users into # running them against RT) it's incredibly useful to be able to link - # to a search result or bookmark a result page. + # to a search result (or chart) or bookmark a result page. '/Search/Results.html' => 1, '/Search/Simple.html' => 1, - '/m/tickets/search' => 1, + '/m/tickets/search' => 1, + '/Search/Chart.html' => 1, + + # This page takes Attachment and Transaction argument to figure + # out what to show, but it's read only and will deny information if you + # don't have ShowOutgoingEmail. + '/Ticket/ShowEmailRecord.html' => 1, ); # Components which are blacklisted from automatic, argument-based whitelisting. @@ -1762,7 +1772,7 @@ sub CreateTicket { $RT::Logger->error("Couldn't make multipart message") if !$rv || $rv !~ /^(?:DONE|ALREADY)$/; - foreach ( values %{ $ARGS{'Attachments'} } ) { + foreach ( map $ARGS{Attachments}->{$_}, sort keys %{ $ARGS{'Attachments'} } ) { unless ($_) { $RT::Logger->error("Couldn't add empty attachemnt"); next; @@ -1930,6 +1940,9 @@ is true. =cut +# change from stock: if txn custom fields are set but there's no content +# or attachment, create a Touch txn instead of doing nothing + sub ProcessUpdateMessage { my %args = ( @@ -1953,14 +1966,33 @@ sub ProcessUpdateMessage { CurrentUser => $args{'TicketObj'}->CurrentUser, ); - # If, after stripping the signature, we have no message, move the - # UpdateTimeWorked into adjusted TimeWorked, so that a later - # ProcessBasics can deal -- then bail out. + my %txn_customfields; + + foreach my $key ( keys %{ $args{ARGSRef} } ) { + if ( $key =~ /^(?:Object-RT::Transaction--)?CustomField-(\d+)/ ) { + next if $key =~ /(TimeUnits|Magic)$/; + $txn_customfields{$key} = $args{ARGSRef}->{$key}; + } + } + + # If, after stripping the signature, we have no message, create a + # Touch transaction if necessary if ( not $args{ARGSRef}->{'UpdateAttachments'} and not length $args{ARGSRef}->{'UpdateContent'} ) { - if ( $args{ARGSRef}->{'UpdateTimeWorked'} ) { - $args{ARGSRef}->{TimeWorked} = $args{TicketObj}->TimeWorked + delete $args{ARGSRef}->{'UpdateTimeWorked'}; + #if ( $args{ARGSRef}->{'UpdateTimeWorked'} ) { + # $args{ARGSRef}->{TimeWorked} = $args{TicketObj}->TimeWorked + + # delete $args{ARGSRef}->{'UpdateTimeWorked'}; + # } + + my $timetaken = $args{ARGSRef}->{'UpdateTimeWorked'}; + if ( $timetaken or grep {length $_} values %txn_customfields ) { + my ( $Transaction, $Description, $Object ) = + $args{TicketObj}->Touch( + CustomFields => \%txn_customfields, + TimeTaken => $timetaken + ); + return $Description; } return; } @@ -1995,7 +2027,8 @@ sub ProcessUpdateMessage { if ( $args{ARGSRef}->{'UpdateAttachments'} ) { $Message->make_multipart; - $Message->add_part($_) foreach values %{ $args{ARGSRef}->{'UpdateAttachments'} }; + $Message->add_part($_) foreach map $args{ARGSRef}->{UpdateAttachments}{$_}, + sort keys %{ $args{ARGSRef}->{'UpdateAttachments'} }; } if ( $args{ARGSRef}->{'AttachTickets'} ) { @@ -2006,14 +2039,6 @@ sub ProcessUpdateMessage { : ( $args{ARGSRef}->{'AttachTickets'} ) ); } - my %txn_customfields; - - foreach my $key ( keys %{ $args{ARGSRef} } ) { - if ( $key =~ /^(?:Object-RT::Transaction--)?CustomField-(\d+)/ ) { - $txn_customfields{$key} = $args{ARGSRef}->{$key}; - } - } - my %message_args = ( Sign => ( $args{ARGSRef}->{'Sign'} ? 1 : 0 ), Encrypt => ( $args{ARGSRef}->{'Encrypt'} ? 1 : 0 ), @@ -2070,7 +2095,6 @@ sub _ProcessUpdateMessageRecipients { if (grep $_ eq 'Requestor' || $_ eq 'Requestors', @{ $args{ARGSRef}->{'SkipNotification'} || [] }) { push @txn_squelch, map $_->address, Email::Address->parse( $message_args->{Requestor} ); push @txn_squelch, $args{TicketObj}->Requestors->MemberEmailAddresses; - } push @txn_squelch, @{$args{ARGSRef}{SquelchMailTo}} if $args{ARGSRef}{SquelchMailTo}; @@ -2092,6 +2116,39 @@ sub _ProcessUpdateMessageRecipients { } } +sub ProcessAttachments { + my %args = ( + ARGSRef => {}, + @_ + ); + + my $ARGSRef = $args{ARGSRef} || {}; + # deal with deleting uploaded attachments + foreach my $key ( keys %$ARGSRef ) { + if ( $key =~ m/^DeleteAttach-(.+)$/ ) { + delete $session{'Attachments'}{$1}; + } + $session{'Attachments'} = { %{ $session{'Attachments'} || {} } }; + } + + # store the uploaded attachment in session + if ( defined $ARGSRef->{'Attach'} && length $ARGSRef->{'Attach'} ) + { # attachment? + my $attachment = MakeMIMEEntity( AttachmentFieldName => 'Attach' ); + + my $file_path = Encode::decode_utf8("$ARGSRef->{'Attach'}"); + $session{'Attachments'} = + { %{ $session{'Attachments'} || {} }, $file_path => $attachment, }; + } + + # delete temporary storage entry to make WebUI clean + unless ( keys %{ $session{'Attachments'} } and $ARGSRef->{'UpdateAttach'} ) + { + delete $session{'Attachments'}; + } +} + + =head2 MakeMIMEEntity PARAMHASH Takes a paramhash Subject, Body and AttachmentFieldName. @@ -2174,37 +2231,6 @@ sub MakeMIMEEntity { } -sub ProcessAttachments { - my %args = ( - ARGSRef => {}, - @_ - ); - - my $ARGSRef = $args{ARGSRef} || {}; - # deal with deleting uploaded attachments - foreach my $key ( keys %$ARGSRef ) { - if ( $key =~ m/^DeleteAttach-(.+)$/ ) { - delete $session{'Attachments'}{$1}; - } - $session{'Attachments'} = { %{ $session{'Attachments'} || {} } }; - } - - # store the uploaded attachment in session - if ( defined $ARGSRef->{'Attach'} && length $ARGSRef->{'Attach'} ) - { # attachment? - my $attachment = MakeMIMEEntity( AttachmentFieldName => 'Attach' ); - - my $file_path = Encode::decode_utf8("$ARGSRef->{'Attach'}"); - $session{'Attachments'} = - { %{ $session{'Attachments'} || {} }, $file_path => $attachment, }; - } - - # delete temporary storage entry to make WebUI clean - unless ( keys %{ $session{'Attachments'} } and $ARGSRef->{'UpdateAttach'} ) - { - delete $session{'Attachments'}; - } -} =head2 ParseDateToISO @@ -2604,18 +2630,23 @@ sub ProcessTicketReminders { while ( my $reminder = $reminder_collection->Next ) { my $resolve_status = $reminder->QueueObj->Lifecycle->ReminderStatusOnResolve; if ( $reminder->Status ne $resolve_status && $args->{ 'Complete-Reminder-' . $reminder->id } ) { - $Ticket->Reminders->Resolve($reminder); + my ($status, $msg) = $Ticket->Reminders->Resolve($reminder); + push @results, loc("Reminder #[_1]: [_2]", $reminder->id, $msg); + } elsif ( $reminder->Status eq $resolve_status && !$args->{ 'Complete-Reminder-' . $reminder->id } ) { - $Ticket->Reminders->Open($reminder); + my ($status, $msg) = $Ticket->Reminders->Open($reminder); + push @results, loc("Reminder #[_1]: [_2]", $reminder->id, $msg); } if ( exists( $args->{ 'Reminder-Subject-' . $reminder->id } ) && ( $reminder->Subject ne $args->{ 'Reminder-Subject-' . $reminder->id } )) { - $reminder->SetSubject( $args->{ 'Reminder-Subject-' . $reminder->id } ) ; + my ($status, $msg) = $reminder->SetSubject( $args->{ 'Reminder-Subject-' . $reminder->id } ) ; + push @results, loc("Reminder #[_1]: [_2]", $reminder->id, $msg); } if ( exists( $args->{ 'Reminder-Owner-' . $reminder->id } ) && ( $reminder->Owner != $args->{ 'Reminder-Owner-' . $reminder->id } )) { - $reminder->SetOwner( $args->{ 'Reminder-Owner-' . $reminder->id } , "Force" ) ; + my ($status, $msg) = $reminder->SetOwner( $args->{ 'Reminder-Owner-' . $reminder->id } , "Force" ) ; + push @results, loc("Reminder #[_1]: [_2]", $reminder->id, $msg); } if ( exists( $args->{ 'Reminder-Due-' . $reminder->id } ) && $args->{ 'Reminder-Due-' . $reminder->id } ne '' ) { @@ -2625,7 +2656,8 @@ sub ProcessTicketReminders { Value => $args->{ 'Reminder-Due-' . $reminder->id } ); if ( defined $DateObj->Unix && $DateObj->Unix != $reminder->DueObj->Unix ) { - $reminder->SetDue( $DateObj->ISO ); + my ($status, $msg) = $reminder->SetDue( $DateObj->ISO ); + push @results, loc("Reminder #[_1]: [_2]", $reminder->id, $msg); } } } @@ -3165,7 +3197,8 @@ sub GetColumnMapEntry { } # complex things - elsif ( my ( $mainkey, $subkey ) = $args{'Name'} =~ /^(.*?)\.{(.+)}$/ ) { + elsif ( my ( $mainkey, $subkey ) = $args{'Name'} =~ /^(.*?)\.(.+)$/ ) { + $subkey =~ s/^\{(.*)\}$/$1/; return undef unless $args{'Map'}->{$mainkey}; return $args{'Map'}{$mainkey}{ $args{'Attribute'} } unless ref $args{'Map'}{$mainkey}{ $args{'Attribute'} } eq 'CODE';