diff options
author | Ivan Kohler <ivan@freeside.biz> | 2012-06-30 01:03:13 -0700 |
---|---|---|
committer | Ivan Kohler <ivan@freeside.biz> | 2012-06-30 01:03:13 -0700 |
commit | f3c4966ed1f6ec3db7accd6dcdd3a5a3821d72a7 (patch) | |
tree | e5e9a077260613e6117d4697dd2985abd9b03d34 /rt/lib/RT/Action | |
parent | cf7cd8efc7095aadbdfb0cd8e7ea0e2e8b9e9085 (diff) | |
parent | cd3eb95ed1f3dc3e04cfc2b3b405f75b3ab086da (diff) |
merging RT 4.0.6
Diffstat (limited to 'rt/lib/RT/Action')
-rw-r--r-- | rt/lib/RT/Action/AutoOpen.pm | 57 | ||||
-rwxr-xr-x | rt/lib/RT/Action/Autoreply.pm | 8 | ||||
-rw-r--r-- | rt/lib/RT/Action/CreateTickets.pm | 64 | ||||
-rw-r--r-- | rt/lib/RT/Action/EscalatePriority.pm | 9 | ||||
-rw-r--r-- | rt/lib/RT/Action/ExtractSubjectTag.pm | 8 | ||||
-rwxr-xr-x | rt/lib/RT/Action/Generic.pm | 73 | ||||
-rwxr-xr-x | rt/lib/RT/Action/LinearEscalate.pm | 2 | ||||
-rwxr-xr-x | rt/lib/RT/Action/Notify.pm | 29 | ||||
-rwxr-xr-x | rt/lib/RT/Action/NotifyAsComment.pm | 2 | ||||
-rw-r--r-- | rt/lib/RT/Action/NotifyGroup.pm | 2 | ||||
-rw-r--r-- | rt/lib/RT/Action/NotifyGroupAsComment.pm | 2 | ||||
-rw-r--r-- | rt/lib/RT/Action/RecordComment.pm | 2 | ||||
-rw-r--r-- | rt/lib/RT/Action/RecordCorrespondence.pm | 2 | ||||
-rw-r--r-- | rt/lib/RT/Action/ResolveMembers.pm | 108 | ||||
-rwxr-xr-x | rt/lib/RT/Action/SendEmail.pm | 166 | ||||
-rw-r--r-- | rt/lib/RT/Action/SetPriority.pm | 6 | ||||
-rw-r--r-- | rt/lib/RT/Action/SetStatus.pm | 152 | ||||
-rw-r--r-- | rt/lib/RT/Action/UserDefined.pm | 2 |
18 files changed, 370 insertions, 324 deletions
diff --git a/rt/lib/RT/Action/AutoOpen.pm b/rt/lib/RT/Action/AutoOpen.pm index b99b21474..5f96e0649 100644 --- a/rt/lib/RT/Action/AutoOpen.pm +++ b/rt/lib/RT/Action/AutoOpen.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC # <sales@bestpractical.com> # # (Except where explicitly superseded by other copyright notices) @@ -51,49 +51,64 @@ package RT::Action::AutoOpen; use strict; use warnings; - use base qw(RT::Action); =head1 DESCRIPTION -Opens a ticket unless it's allready open, but only unless transaction -L<RT::Transaction/IsInbound is inbound>. +This action automatically moves a ticket to an active status. + +Status is not changed if there is no active statuses in the lifecycle. + +Status is not changed if the current status is first active for ticket's status +lifecycle. For example if ticket's status is 'processing' and active statuses are +'processing', 'on hold' and 'waiting' then status is not changed, but for ticket +with status 'on hold' other rules are checked. + +Status is not changed if it's in the list of C<initial> statuses for the +current scheme and creator of the current transaction +is one of the ticket's requestors. -Doesn't open a ticket if message's head has field C<RT-Control> with -C<no-autoopen> substring. +Status is not changed if message's head has field C<RT-Control> with C<no-autoopen> +substring. + +Status is set to the first possible active status. If the ticket's +status is C<Stalled> then RT finds all possible transitions from C<Stalled> +status and selects first one that results in the ticket having an +active status. =cut sub Prepare { my $self = shift; - # if the ticket is already open or the ticket is new and the message is more mail from the - # requestor, don't reopen it. + my $ticket = $self->TicketObj; + my $next = $ticket->FirstActiveStatus; + return 1 unless defined $next; - my $status = $self->TicketObj->Status; - return undef if $status eq 'open'; - return undef if $status eq 'new' && $self->TransactionObj->IsInbound; + # no change if the ticket is in initial status and the message is a mail + # from a requestor + return 1 if $ticket->QueueObj->Lifecycle->IsInitial($ticket->Status) + && $self->TransactionObj->IsInbound; if ( my $msg = $self->TransactionObj->Message->First ) { - return undef if ($msg->GetHeader('RT-Control') || '') =~ /\bno-autoopen\b/i; + return 1 if ($msg->GetHeader('RT-Control') || '') =~ /\bno-autoopen\b/i; } + $self->{'set_status_to'} = $next; + return 1; } sub Commit { my $self = shift; - my $oldstatus = $self->TicketObj->Status; - $self->TicketObj->__Set( Field => 'Status', Value => 'open' ); - $self->TicketObj->_NewTransaction( - Type => 'Status', - Field => 'Status', - OldValue => $oldstatus, - NewValue => 'open', - Data => 'Ticket auto-opened on incoming correspondence' - ); + return 1 unless my $new_status = $self->{'set_status_to'}; + my ($val, $msg) = $self->TicketObj->SetStatus( $new_status ); + unless ( $val ) { + $RT::Logger->error( "Couldn't auto-open ticket: ". $msg ); + return 0; + } return 1; } diff --git a/rt/lib/RT/Action/Autoreply.pm b/rt/lib/RT/Action/Autoreply.pm index e3e792ea7..cde874e45 100755 --- a/rt/lib/RT/Action/Autoreply.pm +++ b/rt/lib/RT/Action/Autoreply.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC # <sales@bestpractical.com> # # (Except where explicitly superseded by other copyright notices) @@ -66,7 +66,6 @@ sub Prepare { $self->SUPER::Prepare(); } -# {{{ sub SetRecipients =head2 SetRecipients @@ -83,10 +82,8 @@ sub SetRecipients { return(1); } -# }}} -# {{{ sub SetReturnAddress =head2 SetReturnAddress @@ -108,9 +105,7 @@ sub SetReturnAddress { } -# }}} -# {{{{ sub SetRTSpecialHeaders =head2 SetRTSpecialHeaders @@ -125,7 +120,6 @@ sub SetRTSpecialHeaders { $self->SetHeader( 'Auto-Submitted', 'auto-replied' ); } -# }}} RT::Base->_ImportOverlays(); diff --git a/rt/lib/RT/Action/CreateTickets.pm b/rt/lib/RT/Action/CreateTickets.pm index fd3e77c3a..31489c8ff 100644 --- a/rt/lib/RT/Action/CreateTickets.pm +++ b/rt/lib/RT/Action/CreateTickets.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC # <sales@bestpractical.com> # # (Except where explicitly superseded by other copyright notices) @@ -130,14 +130,14 @@ A convoluted example # of which the creator of this ticket is a member my $name = "HR"; - my $groups = RT::Groups->new($RT::SystemUser); + my $groups = RT::Groups->new(RT->SystemUser); $groups->LimitToUserDefinedGroups(); $groups->Limit(FIELD => "Name", OPERATOR => "=", VALUE => "$name"); $groups->WithMember($TransactionObj->CreatorObj->Id); my $groupid = $groups->First->Id; - my $adminccs = RT::Users->new($RT::SystemUser); + my $adminccs = RT::Users->new(RT->SystemUser); $adminccs->WhoHaveRight( Right => "AdminGroup", Object =>$groups->First, @@ -196,6 +196,9 @@ A complete list of acceptable fields for this beastie: + Requestor => Email address + Cc => Email address + AdminCc => Email address + + RequestorGroup => Group name + + CcGroup => Group name + + AdminCcGroup => Group name TimeWorked => TimeEstimated => TimeLeft => @@ -230,7 +233,7 @@ by repeating the fieldname on a new line with an additional value. Fields marked with a ! are postponed to be processed after all tickets in the same actions are created. Except for 'Status', those field can also take a ticket name within the same action (i.e. -the identifiers after ==Create-Ticket), instead of raw Ticket ID +the identifiers after ===Create-Ticket), instead of raw Ticket ID numbers. When parsed, field names are converted to lowercase and have -s stripped. @@ -290,9 +293,7 @@ my %LINKTYPEMAP = ( ); -# {{{ Scrip methods (Commit, Prepare) -# {{{ sub Commit #Do what we need to do and send it out. sub Commit { my $self = shift; @@ -305,9 +306,7 @@ sub Commit { return (1); } -# }}} -# {{{ sub Prepare sub Prepare { my $self = shift; @@ -326,17 +325,25 @@ sub Prepare { } + my $active = 0; + if ( $self->TemplateObj->Type eq 'Perl' ) { + $active = 1; + } else { + RT->Logger->info(sprintf( + "Template #%d is type %s. You most likely want to use a Perl template instead.", + $self->TemplateObj->id, $self->TemplateObj->Type + )); + } + $self->Parse( Content => $self->TemplateObj->Content, - _ActiveContent => 1 + _ActiveContent => $active, ); return 1; } -# }}} -# }}} sub CreateByTemplate { my $self = shift; @@ -579,11 +586,15 @@ sub _ParseMultilineTemplate { my %args = (@_); my $template_id; + require Encode; + require utf8; my ( $queue, $requestor ); $RT::Logger->debug("Line: ==="); foreach my $line ( split( /\n/, $args{'Content'} ) ) { $line =~ s/\r$//; - $RT::Logger->debug("Line: $line"); + $RT::Logger->debug( "Line: " . utf8::is_utf8($line) + ? Encode::encode_utf8($line) + : $line ); if ( $line =~ /^===/ ) { if ( $template_id && !$queue && $args{'Queue'} ) { $self->{'templates'}->{$template_id} @@ -716,7 +727,11 @@ sub ParseLines { $args{$tag} =~ s/^\s+//g; $args{$tag} =~ s/\s+$//g; } - if (($tag =~ /^(requestor|cc|admincc)$/i or grep {lc $_ eq $tag} keys %LINKTYPEMAP) and $args{$tag} =~ /,/) { + if ( + ($tag =~ /^(requestor|cc|admincc)(group)?$/i + or grep {lc $_ eq $tag} keys %LINKTYPEMAP) + and $args{$tag} =~ /,/ + ) { $args{$tag} = [ split /,\s*/, $args{$tag} ]; } } @@ -739,6 +754,21 @@ sub ParseLines { $args{$date} = $dateobj->ISO; } + foreach my $role (qw(requestor cc admincc)) { + next unless my $value = $args{ $role . 'group' }; + + my $group = RT::Group->new( $self->CurrentUser ); + $group->LoadUserDefinedGroup( $value ); + unless ( $group->id ) { + $RT::Logger->error("Couldn't load group '$value'"); + next; + } + + $args{ $role } = $args{ $role } ? [$args{ $role }] : [] + unless ref $args{ $role }; + push @{ $args{ $role } }, $group->PrincipalObj->id; + } + $args{'requestor'} ||= $self->TicketObj->Requestors->MemberEmailAddresses if $self->TicketObj; @@ -781,14 +811,17 @@ sub ParseLines { my $orig_tag = $original_tags{$tag} or next; if ( $orig_tag =~ /^customfield-?(\d+)$/i ) { $ticketargs{ "CustomField-" . $1 } = $args{$tag}; - } elsif ( $orig_tag =~ /^(?:customfield|cf)-?(.*)$/i ) { + } elsif ( $orig_tag =~ /^(?:customfield|cf)-?(.+)$/i ) { my $cf = RT::CustomField->new( $self->CurrentUser ); $cf->LoadByName( Name => $1, Queue => $ticketargs{Queue} ); + $cf->LoadByName( Name => $1, Queue => 0 ) unless $cf->id; + next unless $cf->id; $ticketargs{ "CustomField-" . $cf->id } = $args{$tag}; } elsif ($orig_tag) { my $cf = RT::CustomField->new( $self->CurrentUser ); $cf->LoadByName( Name => $orig_tag, Queue => $ticketargs{Queue} ); - next unless ($cf->id) ; + $cf->LoadByName( Name => $orig_tag, Queue => 0 ) unless $cf->id; + next unless $cf->id; $ticketargs{ "CustomField-" . $cf->id } = $args{$tag}; } @@ -1148,6 +1181,7 @@ sub UpdateCustomFields { my $cf = $1; my $CustomFieldObj = RT::CustomField->new($self->CurrentUser); + $CustomFieldObj->SetContextObject( $ticket ); $CustomFieldObj->LoadById($cf); my @values; diff --git a/rt/lib/RT/Action/EscalatePriority.pm b/rt/lib/RT/Action/EscalatePriority.pm index e15e50c84..cb19b4f41 100644 --- a/rt/lib/RT/Action/EscalatePriority.pm +++ b/rt/lib/RT/Action/EscalatePriority.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC # <sales@bestpractical.com> # # (Except where explicitly superseded by other copyright notices) @@ -67,6 +67,9 @@ to final priority. In this way, priority is either increased or decreased toward the final priority as the ticket heads toward its due date. +Alternately, if you don't set a due date, the Priority will be incremented by 1 +until it reaches the Final Priority. If a ticket without a due date has a Priority +greater than Final Priority, it will be decremented by 1. =cut @@ -80,15 +83,12 @@ use strict; #What does this type of Action does -# {{{ sub Describe sub Describe { my $self = shift; return (ref $self . " will move a ticket's priority toward its final priority."); } -# }}} -# {{{ sub Prepare sub Prepare { my $self = shift; @@ -152,7 +152,6 @@ sub Prepare { } return 1; } -# }}} sub Commit { my $self = shift; diff --git a/rt/lib/RT/Action/ExtractSubjectTag.pm b/rt/lib/RT/Action/ExtractSubjectTag.pm index 7121c1327..a4d6458cb 100644 --- a/rt/lib/RT/Action/ExtractSubjectTag.pm +++ b/rt/lib/RT/Action/ExtractSubjectTag.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC # <sales@bestpractical.com> # # (Except where explicitly superseded by other copyright notices) @@ -63,13 +63,15 @@ sub Commit { my $self = shift; my $Transaction = $self->TransactionObj; my $FirstAttachment = $Transaction->Attachments->First; - return 1 unless ($FirstAttachment); + return 1 unless $FirstAttachment; + + my $TransactionSubject = $FirstAttachment->Subject; + return 1 unless $TransactionSubject; my $Ticket = $self->TicketObj; my $TicketSubject = $self->TicketObj->Subject; my $origTicketSubject = $TicketSubject; - my $TransactionSubject = $FirstAttachment->Subject; my $match = RT->Config->Get('ExtractSubjectTagMatch'); my $nomatch = RT->Config->Get('ExtractSubjectTagNoMatch'); diff --git a/rt/lib/RT/Action/Generic.pm b/rt/lib/RT/Action/Generic.pm deleted file mode 100755 index d747813f0..000000000 --- a/rt/lib/RT/Action/Generic.pm +++ /dev/null @@ -1,73 +0,0 @@ -# BEGIN BPS TAGGED BLOCK {{{ -# -# COPYRIGHT: -# -# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC -# <sales@bestpractical.com> -# -# (Except where explicitly superseded by other copyright notices) -# -# -# LICENSE: -# -# This work is made available to you under the terms of Version 2 of -# the GNU General Public License. A copy of that license should have -# been provided with this software, but in any event can be snarfed -# from www.gnu.org. -# -# This work is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -# 02110-1301 or visit their web page on the internet at -# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html. -# -# -# CONTRIBUTION SUBMISSION POLICY: -# -# (The following paragraph is not intended to limit the rights granted -# to you to modify and distribute this software under the terms of -# the GNU General Public License and is only of importance to you if -# you choose to contribute your changes and enhancements to the -# community by submitting them to Best Practical Solutions, LLC.) -# -# By intentionally submitting any modifications, corrections or -# derivatives to this work, or any other work intended for use with -# Request Tracker, to Best Practical Solutions, LLC, you confirm that -# you are the copyright holder for those contributions and you grant -# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable, -# royalty-free, perpetual, license to use, copy, create derivative -# works based on those contributions, and sublicense and distribute -# those contributions and any derivatives thereof. -# -# END BPS TAGGED BLOCK }}} - -=head1 NAME - - RT::Action::Generic - deprecated, see RT::Action - -=head1 SYNOPSIS - - use RT::Action::Generic; - -=head1 DESCRIPTION - -This module is provided only for backwards compatibility. - -=head1 METHODS - - -=cut - -use strict; -use warnings; -package RT::Action::Generic; -use base 'RT::Action'; - -RT::Base->_ImportOverlays(); -1; - diff --git a/rt/lib/RT/Action/LinearEscalate.pm b/rt/lib/RT/Action/LinearEscalate.pm index 3e54320cb..0a0825e82 100755 --- a/rt/lib/RT/Action/LinearEscalate.pm +++ b/rt/lib/RT/Action/LinearEscalate.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC # <sales@bestpractical.com> # # (Except where explicitly superseded by other copyright notices) diff --git a/rt/lib/RT/Action/Notify.pm b/rt/lib/RT/Action/Notify.pm index 3f58bf52f..f1aef4092 100755 --- a/rt/lib/RT/Action/Notify.pm +++ b/rt/lib/RT/Action/Notify.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC # <sales@bestpractical.com> # # (Except where explicitly superseded by other copyright notices) @@ -87,17 +87,6 @@ sub SetRecipients { my ( @To, @PseudoTo, @Cc, @Bcc ); - if ( $arg =~ /\bOtherRecipients\b/ ) { - if ( my $attachment = $self->TransactionObj->Attachments->First ) { - push @Cc, map { $_->address } Email::Address->parse( - $attachment->GetHeader('RT-Send-Cc') - ); - push @Bcc, map { $_->address } Email::Address->parse( - $attachment->GetHeader('RT-Send-Bcc') - ); - } - } - if ( $arg =~ /\bRequestor\b/ ) { push @To, $ticket->Requestors->MemberEmailAddresses; } @@ -115,7 +104,10 @@ sub SetRecipients { } } - if ( $arg =~ /\bOwner\b/ && $ticket->OwnerObj->id != $RT::Nobody->id ) { + if ( $arg =~ /\bOwner\b/ + && $ticket->OwnerObj->id != RT->Nobody->id + && $ticket->OwnerObj->EmailAddress + ) { # If we're not sending to Ccs or requestors, # then the Owner can be the To. if (@To) { @@ -140,7 +132,7 @@ sub SetRecipients { } my $creatorObj = $self->TransactionObj->CreatorObj; - my $creator = $creatorObj->EmailAddress(); + my $creator = $creatorObj->EmailAddress() || ''; #Strip the sender out of the To, Cc and AdminCc and set the # recipients fields used to build the message by the superclass. @@ -159,7 +151,14 @@ sub SetRecipients { } @{ $self->{'PseudoTo'} } = @PseudoTo; - + if ( $arg =~ /\bOtherRecipients\b/ ) { + if ( my $attachment = $self->TransactionObj->Attachments->First ) { + push @{ $self->{'NoSquelch'}{'Cc'} ||= [] }, map $_->address, + Email::Address->parse( $attachment->GetHeader('RT-Send-Cc') ); + push @{ $self->{'NoSquelch'}{'Bcc'} ||= [] }, map $_->address, + Email::Address->parse( $attachment->GetHeader('RT-Send-Bcc') ); + } + } } RT::Base->_ImportOverlays(); diff --git a/rt/lib/RT/Action/NotifyAsComment.pm b/rt/lib/RT/Action/NotifyAsComment.pm index 504d139c0..b62f55599 100755 --- a/rt/lib/RT/Action/NotifyAsComment.pm +++ b/rt/lib/RT/Action/NotifyAsComment.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC # <sales@bestpractical.com> # # (Except where explicitly superseded by other copyright notices) diff --git a/rt/lib/RT/Action/NotifyGroup.pm b/rt/lib/RT/Action/NotifyGroup.pm index a0efd5b8f..5e7076f39 100644 --- a/rt/lib/RT/Action/NotifyGroup.pm +++ b/rt/lib/RT/Action/NotifyGroup.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC # <sales@bestpractical.com> # # (Except where explicitly superseded by other copyright notices) diff --git a/rt/lib/RT/Action/NotifyGroupAsComment.pm b/rt/lib/RT/Action/NotifyGroupAsComment.pm index a5bc49c3a..151189033 100644 --- a/rt/lib/RT/Action/NotifyGroupAsComment.pm +++ b/rt/lib/RT/Action/NotifyGroupAsComment.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC # <sales@bestpractical.com> # # (Except where explicitly superseded by other copyright notices) diff --git a/rt/lib/RT/Action/RecordComment.pm b/rt/lib/RT/Action/RecordComment.pm index 5d3664d16..62832a5f4 100644 --- a/rt/lib/RT/Action/RecordComment.pm +++ b/rt/lib/RT/Action/RecordComment.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC # <sales@bestpractical.com> # # (Except where explicitly superseded by other copyright notices) diff --git a/rt/lib/RT/Action/RecordCorrespondence.pm b/rt/lib/RT/Action/RecordCorrespondence.pm index 109c0df91..2faa56019 100644 --- a/rt/lib/RT/Action/RecordCorrespondence.pm +++ b/rt/lib/RT/Action/RecordCorrespondence.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC # <sales@bestpractical.com> # # (Except where explicitly superseded by other copyright notices) diff --git a/rt/lib/RT/Action/ResolveMembers.pm b/rt/lib/RT/Action/ResolveMembers.pm deleted file mode 100644 index aff636558..000000000 --- a/rt/lib/RT/Action/ResolveMembers.pm +++ /dev/null @@ -1,108 +0,0 @@ -# BEGIN BPS TAGGED BLOCK {{{ -# -# COPYRIGHT: -# -# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC -# <sales@bestpractical.com> -# -# (Except where explicitly superseded by other copyright notices) -# -# -# LICENSE: -# -# This work is made available to you under the terms of Version 2 of -# the GNU General Public License. A copy of that license should have -# been provided with this software, but in any event can be snarfed -# from www.gnu.org. -# -# This work is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -# 02110-1301 or visit their web page on the internet at -# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html. -# -# -# CONTRIBUTION SUBMISSION POLICY: -# -# (The following paragraph is not intended to limit the rights granted -# to you to modify and distribute this software under the terms of -# the GNU General Public License and is only of importance to you if -# you choose to contribute your changes and enhancements to the -# community by submitting them to Best Practical Solutions, LLC.) -# -# By intentionally submitting any modifications, corrections or -# derivatives to this work, or any other work intended for use with -# Request Tracker, to Best Practical Solutions, LLC, you confirm that -# you are the copyright holder for those contributions and you grant -# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable, -# royalty-free, perpetual, license to use, copy, create derivative -# works based on those contributions, and sublicense and distribute -# those contributions and any derivatives thereof. -# -# END BPS TAGGED BLOCK }}} - -# This Action will resolve all members of a resolved group ticket - -package RT::Action::ResolveMembers; -use base 'RT::Action'; -require RT::Links; - -use strict; - -#Do what we need to do and send it out. - -#What does this type of Action does - -# {{{ sub Describe -sub Describe { - my $self = shift; - return $self->loc("[_1] will resolve all members of a resolved group ticket.", ref $self); -} -# }}} - - -# {{{ sub Prepare -sub Prepare { - # nothing to prepare - return 1; -} -# }}} - -sub Commit { - my $self = shift; - - my $Links=RT::Links->new($RT::SystemUser); - $Links->Limit(FIELD => 'Type', VALUE => 'MemberOf'); - $Links->Limit(FIELD => 'Target', VALUE => $self->TicketObj->id); - - while (my $Link=$Links->Next()) { - # Todo: Try to deal with remote URIs as well - next unless $Link->BaseURI->IsLocal; - my $base=RT::Ticket->new($self->TicketObj->CurrentUser); - # Todo: Only work if Base is a plain ticket num: - $base->Load($Link->Base); - # I'm afraid this might be a major bottleneck if ResolveGroupTicket is on. - $base->Resolve; - } -} - - -# Applicability checked in Commit. - -# {{{ sub IsApplicable -sub IsApplicable { - my $self = shift; - 1; - return 1; -} -# }}} - -RT::Base->_ImportOverlays(); - -1; - diff --git a/rt/lib/RT/Action/SendEmail.pm b/rt/lib/RT/Action/SendEmail.pm index 9e93e4aab..4ae1a8b66 100755 --- a/rt/lib/RT/Action/SendEmail.pm +++ b/rt/lib/RT/Action/SendEmail.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC # <sales@bestpractical.com> # # (Except where explicitly superseded by other copyright notices) @@ -80,13 +80,12 @@ RT::Action::SendEmail. =head2 CleanSlate -Cleans class-wide options, like L</SquelchMailTo> or L</AttachTickets>. +Cleans class-wide options, like L</AttachTickets>. =cut sub CleanSlate { my $self = shift; - $self->SquelchMailTo(undef); $self->AttachTickets(undef); } @@ -166,8 +165,6 @@ sub Prepare { # Header $self->SetRTSpecialHeaders(); - $self->RemoveInappropriateRecipients(); - my %seen; foreach my $type (@EMAIL_RECIPIENT_HEADERS) { @{ $self->{$type} } @@ -175,6 +172,8 @@ sub Prepare { @{ $self->{$type} }; } + $self->RemoveInappropriateRecipients(); + # Go add all the Tos, Ccs and Bccs that we need to to the message to # make it happy, but only if we actually have values in those arrays. @@ -349,7 +348,7 @@ sub AddAttachments { $MIMEObj->head->delete('RT-Attach-Message'); - my $attachments = RT::Attachments->new($RT::SystemUser); + my $attachments = RT::Attachments->new( RT->SystemUser ); $attachments->Limit( FIELD => 'TransactionId', VALUE => $self->TransactionObj->Id @@ -409,11 +408,20 @@ sub AddAttachment { my $attach = shift; my $MIMEObj = shift || $self->TemplateObj->MIMEObj; + # $attach->TransactionObj may not always be $self->TransactionObj + return unless $attach->Id + and $attach->TransactionObj->CurrentUserCanSee; + + # ->attach expects just the disposition type; extract it if we have the header + my $disp = ($attach->GetHeader('Content-Disposition') || '') + =~ /^\s*(inline|attachment)/i ? $1 : undef; + $MIMEObj->attach( - Type => $attach->ContentType, - Charset => $attach->OriginalEncoding, - Data => $attach->OriginalContent, - Filename => $self->MIMEEncodeString( $attach->Filename ), + Type => $attach->ContentType, + Charset => $attach->OriginalEncoding, + Data => $attach->OriginalContent, + Disposition => $disp, # a false value defaults to inline in MIME::Entity + Filename => $self->MIMEEncodeString( $attach->Filename ), 'RT-Attachment:' => $self->TicketObj->Id . "/" . $self->TransactionObj->Id . "/" . $attach->id, @@ -467,8 +475,7 @@ sub AddTicket { my $self = shift; my $tid = shift; - # XXX: we need a current user here, but who is current user? - my $attachs = RT::Attachments->new($RT::SystemUser); + my $attachs = RT::Attachments->new( $self->TransactionObj->CreatorObj ); my $txn_alias = $attachs->TransactionAlias; $attachs->Limit( ALIAS => $txn_alias, FIELD => 'Type', VALUE => 'Create' ); $attachs->Limit( @@ -660,7 +667,7 @@ sub DeferDigestRecipients { $RT::Logger->debug( $self->TemplateObj->MIMEObj->head->as_string ); foreach my $rcpt ( map { $_->address } $self->AddressesFromHeader($mailfield) ) { next unless $rcpt; - my $user_obj = RT::User->new($RT::SystemUser); + my $user_obj = RT::User->new(RT->SystemUser); $user_obj->LoadByEmail($rcpt); if ( ! $user_obj->id ) { # If there's an email address in here without an associated @@ -729,26 +736,15 @@ sub RecordDeferredRecipients { return ($ret,$msg); } -=head2 SquelchMailTo [@ADDRESSES] - -Mark ADDRESSES to be removed from list of the recipients. Returns list of the addresses. -To empty list pass undefined argument. +=head2 SquelchMailTo -B<Note> that this method can be called as class method and works globaly. Don't forget to -clean this list when blocking is not required anymore, pass undef to do this. +Returns list of the addresses to squelch on this transaction. =cut -{ - my $squelch = []; - - sub SquelchMailTo { - my $self = shift; - if (@_) { - $squelch = [ grep defined, @_ ]; - } - return @$squelch; - } +sub SquelchMailTo { + my $self = shift; + return map $_->Content, $self->TransactionObj->SquelchMailTo; } =head2 RemoveInappropriateRecipients @@ -789,9 +785,9 @@ sub RemoveInappropriateRecipients { # Only send to "privileged" watchers. foreach my $type (@EMAIL_RECIPIENT_HEADERS) { foreach my $addr ( @{ $self->{$type} } ) { - my $user = RT::User->new($RT::SystemUser); + my $user = RT::User->new(RT->SystemUser); $user->LoadByEmail($addr); - push @blacklist, $addr if ( !$user->Privileged ); + push @blacklist, $addr unless $user->id && $user->Privileged; } } $RT::Logger->info( $msgid @@ -806,15 +802,15 @@ sub RemoveInappropriateRecipients { } } -# Let's grab the SquelchMailTo attribue and push those entries into the @blacklist - push @blacklist, map $_->Content, $self->TicketObj->SquelchMailTo; - push @blacklist, $self->SquelchMailTo; + # Let's grab the SquelchMailTo attributes and push those entries into the @blacklisted + push @blacklist, map $_->Content, $self->TicketObj->SquelchMailTo, $self->TransactionObj->SquelchMailTo; # Cycle through the people we're sending to and pull out anyone on the # system blacklist # Trim leading and trailing spaces. - @blacklist = map { RT::User->CanonicalizeEmailAddress( $_->address ) } Email::Address->parse(join(', ', grep {defined} @blacklist)); + @blacklist = map { RT::User->CanonicalizeEmailAddress( $_->address ) } + Email::Address->parse( join ', ', grep defined, @blacklist ); foreach my $type (@EMAIL_RECIPIENT_HEADERS) { my @addrs; @@ -826,12 +822,20 @@ sub RemoveInappropriateRecipients { $RT::Logger->info( $msgid . "$addr appears to point to this RT instance. Skipping" ); next; } - if ( grep /^\Q$addr\E$/, @blacklist ) { + if ( grep $addr eq $_, @blacklist ) { $RT::Logger->info( $msgid . "$addr was blacklisted for outbound mail on this transaction. Skipping"); next; } push @addrs, $addr; } + foreach my $addr ( @{ $self->{'NoSquelch'}{$type} || [] } ) { + # never send email to itself + if ( !RT::EmailParser->CullRTAddresses($addr) ) { + $RT::Logger->info( $msgid . "$addr appears to point to this RT instance. Skipping" ); + next; + } + push @addrs, $addr; + } @{ $self->{$type} } = @addrs; } } @@ -864,36 +868,67 @@ sub SetReturnAddress { } unless ( $self->TemplateObj->MIMEObj->head->get('From') ) { - if ( RT->Config->Get('UseFriendlyFromLine') ) { - my $friendly_name = $args{friendly_name}; + $self->SetFrom( %args, From => $replyto ); + } - unless ( $friendly_name ) { - $friendly_name = $self->TransactionObj->CreatorObj->FriendlyName; - if ( $friendly_name =~ /^"(.*)"$/ ) { # a quoted string - $friendly_name = $1; - } - } + unless ( $self->TemplateObj->MIMEObj->head->get('Reply-To') ) { + $self->SetHeader( 'Reply-To', "$replyto" ); + } - $friendly_name =~ s/"/\\"/g; - $self->SetHeader( - 'From', - sprintf( - RT->Config->Get('FriendlyFromLineFormat'), - $self->MIMEEncodeString( - $friendly_name, RT->Config->Get('EmailOutputEncoding') - ), - $replyto +} + +=head2 SetFrom ( From => emailaddress ) + +Set the From: address for outgoing email + +=cut + +sub SetFrom { + my $self = shift; + my %args = @_; + + if ( RT->Config->Get('UseFriendlyFromLine') ) { + my $friendly_name = $self->GetFriendlyName(%args); + $self->SetHeader( + 'From', + sprintf( + RT->Config->Get('FriendlyFromLineFormat'), + $self->MIMEEncodeString( + $friendly_name, RT->Config->Get('EmailOutputEncoding') ), - ); - } else { - $self->SetHeader( 'From', $replyto ); - } + $args{From} + ), + ); + } else { + $self->SetHeader( 'From', $args{From} ); } +} - unless ( $self->TemplateObj->MIMEObj->head->get('Reply-To') ) { - $self->SetHeader( 'Reply-To', "$replyto" ); +=head2 GetFriendlyName + +Calculate the proper Friendly Name based on the creator of the transaction + +=cut + +sub GetFriendlyName { + my $self = shift; + my %args = ( + is_comment => 0, + friendly_name => '', + @_ + ); + my $friendly_name = $args{friendly_name}; + + unless ( $friendly_name ) { + $friendly_name = $self->TransactionObj->CreatorObj->FriendlyName; + if ( $friendly_name =~ /^"(.*)"$/ ) { # a quoted string + $friendly_name = $1; + } } + $friendly_name =~ s/"/\\"/g; + return $friendly_name; + } =head2 SetHeader FIELD, VALUE @@ -982,16 +1017,17 @@ Set References and In-Reply-To headers for this message. sub SetReferencesHeaders { my $self = shift; - my ( @in_reply_to, @references, @msgid ); - if ( my $top = $self->TransactionObj->Message->First ) { - @in_reply_to = split( /\s+/m, $top->GetHeader('In-Reply-To') || '' ); - @references = split( /\s+/m, $top->GetHeader('References') || '' ); - @msgid = split( /\s+/m, $top->GetHeader('Message-ID') || '' ); - } else { + my $top = $self->TransactionObj->Message->First; + unless ( $top ) { + $self->SetHeader( References => $self->PseudoReference ); return (undef); } + my @in_reply_to = split( /\s+/m, $top->GetHeader('In-Reply-To') || '' ); + my @references = split( /\s+/m, $top->GetHeader('References') || '' ); + my @msgid = split( /\s+/m, $top->GetHeader('Message-ID') || '' ); + # There are two main cases -- this transaction was created with # the RT Web UI, and hence we want to *not* append its Message-ID # to the References and In-Reply-To. OR it came from an outside diff --git a/rt/lib/RT/Action/SetPriority.pm b/rt/lib/RT/Action/SetPriority.pm index 420f9bd24..783d57dd8 100644 --- a/rt/lib/RT/Action/SetPriority.pm +++ b/rt/lib/RT/Action/SetPriority.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC # <sales@bestpractical.com> # # (Except where explicitly superseded by other copyright notices) @@ -55,20 +55,16 @@ use strict; #What does this type of Action does -# {{{ sub Describe sub Describe { my $self = shift; return (ref $self . " will set a ticket's priority to the argument provided."); } -# }}} -# {{{ sub Prepare sub Prepare { # nothing to prepare return 1; } -# }}} sub Commit { my $self = shift; diff --git a/rt/lib/RT/Action/SetStatus.pm b/rt/lib/RT/Action/SetStatus.pm new file mode 100644 index 000000000..f52d401cc --- /dev/null +++ b/rt/lib/RT/Action/SetStatus.pm @@ -0,0 +1,152 @@ +# BEGIN BPS TAGGED BLOCK {{{ +# +# COPYRIGHT: +# +# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC +# <sales@bestpractical.com> +# +# (Except where explicitly superseded by other copyright notices) +# +# +# LICENSE: +# +# This work is made available to you under the terms of Version 2 of +# the GNU General Public License. A copy of that license should have +# been provided with this software, but in any event can be snarfed +# from www.gnu.org. +# +# This work is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301 or visit their web page on the internet at +# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html. +# +# +# CONTRIBUTION SUBMISSION POLICY: +# +# (The following paragraph is not intended to limit the rights granted +# to you to modify and distribute this software under the terms of +# the GNU General Public License and is only of importance to you if +# you choose to contribute your changes and enhancements to the +# community by submitting them to Best Practical Solutions, LLC.) +# +# By intentionally submitting any modifications, corrections or +# derivatives to this work, or any other work intended for use with +# Request Tracker, to Best Practical Solutions, LLC, you confirm that +# you are the copyright holder for those contributions and you grant +# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable, +# royalty-free, perpetual, license to use, copy, create derivative +# works based on those contributions, and sublicense and distribute +# those contributions and any derivatives thereof. +# +# END BPS TAGGED BLOCK }}} + +package RT::Action::SetStatus; + +use strict; +use warnings; +use base qw(RT::Action); + +=head1 NAME + +RT::Action::SetStatus - RT's scrip action to set status of a ticket + +=head1 DESCRIPTION + +This action changes status to a new value according to the rules in L</ARGUMENT>. +Status is not changed if the transition is invalid or another error occurs. All +issues are logged at apropriate levels. + +=head1 ARGUMENT + +Argument can be one of the following: + +=over 4 + +=item status literally + +Status is changed from the current value to a new defined by the argument, +but only if it's valid status and allowed by transitions of the current lifecycle, +for example: + + * The current status is 'stalled' + * Argument of this action is 'open' + * The only possible transition in the scheam from 'stalled' is 'open' + * Status is changed + +However, in the example above Status is not changed if argument is anything +else as it's just not allowed by the lifecycle. + +=item 'initial', 'active' or 'inactive' + +Status is changed from the current value to first possible 'initial', +'active' or 'inactive' correspondingly. First possible value is figured +according to transitions to the target set, for example: + + * The current status is 'open' + * Argument of this action is 'inactive' + * Possible transitions from 'open' are 'resolved', 'rejected' or 'deleted' + * Status is changed to 'resolved' + +=back + +=cut + +sub Prepare { + my $self = shift; + + my $ticket = $self->TicketObj; + my $lifecycle = $ticket->QueueObj->Lifecycle; + my $status = $ticket->Status; + + my $argument = $self->Argument; + unless ( $argument ) { + $RT::Logger->error("Argument is mandatory for SetStatus action"); + return 0; + } + + my $next = ''; + if ( $argument =~ /^(initial|active|inactive)$/i ) { + my $method = 'Is'. ucfirst lc $argument; + ($next) = grep $lifecycle->$method($_), $lifecycle->Transitions($status); + unless ( $next ) { + $RT::Logger->info("No transition from '$status' to $argument set"); + return 1; + } + } + elsif ( $lifecycle->IsValid( $argument ) ) { + unless ( $lifecycle->IsTransition( $status => $argument ) ) { + $RT::Logger->warning("Transition '$status -> $argument' is not valid"); + return 1; + } + $next = $argument; + } + else { + $RT::Logger->error("Argument for SetStatus action is not valid status or one of set"); + return 0; + } + + $self->{'set_status_to'} = $next; + + return 1; +} + +sub Commit { + my $self = shift; + + return 1 unless my $new_status = $self->{'set_status_to'}; + + my ($val, $msg) = $self->TicketObj->SetStatus( $new_status ); + unless ( $val ) { + $RT::Logger->error( "Couldn't set status: ". $msg ); + return 0; + } + return 1; +} + +1; diff --git a/rt/lib/RT/Action/UserDefined.pm b/rt/lib/RT/Action/UserDefined.pm index 3d8e73cb0..1bad2bedd 100644 --- a/rt/lib/RT/Action/UserDefined.pm +++ b/rt/lib/RT/Action/UserDefined.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC # <sales@bestpractical.com> # # (Except where explicitly superseded by other copyright notices) |