diff options
author | ivan <ivan> | 2002-08-12 06:17:09 +0000 |
---|---|---|
committer | ivan <ivan> | 2002-08-12 06:17:09 +0000 |
commit | 3ef62a0570055da710328937e7f65dbb2c027c62 (patch) | |
tree | d549158b172fd499b4f81a2981b62aabbde4f99b /rt/lib/RT/Action | |
parent | 030438c9cb1c12ccb79130979ef0922097b4311a (diff) |
import rt 2.0.14
Diffstat (limited to 'rt/lib/RT/Action')
-rwxr-xr-x | rt/lib/RT/Action/Autoreply.pm | 64 | ||||
-rwxr-xr-x | rt/lib/RT/Action/Generic.pm | 155 | ||||
-rwxr-xr-x | rt/lib/RT/Action/Notify.pm | 99 | ||||
-rwxr-xr-x | rt/lib/RT/Action/NotifyAsComment.pm | 25 | ||||
-rw-r--r-- | rt/lib/RT/Action/OpenDependent.pm | 55 | ||||
-rw-r--r-- | rt/lib/RT/Action/ResolveMembers.pm | 57 | ||||
-rwxr-xr-x | rt/lib/RT/Action/SendEmail.pm | 468 | ||||
-rwxr-xr-x | rt/lib/RT/Action/SendPasswordEmail.pm | 170 | ||||
-rw-r--r-- | rt/lib/RT/Action/StallDependent.pm | 68 |
9 files changed, 1161 insertions, 0 deletions
diff --git a/rt/lib/RT/Action/Autoreply.pm b/rt/lib/RT/Action/Autoreply.pm new file mode 100755 index 000000000..624888e94 --- /dev/null +++ b/rt/lib/RT/Action/Autoreply.pm @@ -0,0 +1,64 @@ +#$Header: /home/cvs/cvsroot/freeside/rt/lib/RT/Action/Autoreply.pm,v 1.1 2002-08-12 06:17:07 ivan Exp $ + +package RT::Action::Autoreply; +require RT::Action::SendEmail; +@ISA = qw(RT::Action::SendEmail); + + +# {{{ sub SetRecipients + +=head2 SetRecipients + +Sets the recipients of this message to this ticket's Requestor. + +=cut + + +sub SetRecipients { + my $self=shift; + + push(@{$self->{'To'}}, @{$self->TicketObj->Requestors->Emails}); + + return(1); +} + +# }}} + + +# {{{ sub SetReturnAddress + +=head2 SetReturnAddress + +Set this message\'s return address to the apropriate queue address + +=cut + +sub SetReturnAddress { + my $self = shift; + my %args = ( is_comment => 0, + @_ + ); + + if ($args{'is_comment'}) { + $replyto = $self->TicketObj->QueueObj->CommentAddress || + $RT::CommentAddress; + } + else { + $replyto = $self->TicketObj->QueueObj->CorrespondAddress || + $RT::CorrespondAddress; + } + + unless ($self->TemplateObj->MIMEObj->head->get('From')) { + my $friendly_name=$self->TicketObj->QueueObj->Name; + $self->SetHeader('From', "\"$friendly_name\" <$replyto>"); + } + + unless ($self->TemplateObj->MIMEObj->head->get('Reply-To')) { + $self->SetHeader('Reply-To', "$replyto"); + } + +} + +# }}} + +1; diff --git a/rt/lib/RT/Action/Generic.pm b/rt/lib/RT/Action/Generic.pm new file mode 100755 index 000000000..ecfd4ab1a --- /dev/null +++ b/rt/lib/RT/Action/Generic.pm @@ -0,0 +1,155 @@ +# $Header: /home/cvs/cvsroot/freeside/rt/lib/RT/Action/Generic.pm,v 1.1 2002-08-12 06:17:07 ivan Exp $ +# (c) 1996-2000 Jesse Vincent <jesse@fsck.com> +# This software is redistributable under the terms of the GNU GPL + +=head1 NAME + + RT::Action::Generic - a generic baseclass for RT Actions + +=head1 SYNOPSIS + + use RT::Action::Generic; + +=head1 DESCRIPTION + +=head1 METHODS + +=begin testing + +ok (require RT::TestHarness); +ok (require RT::Action::Generic); + +=end testing + +=cut + +package RT::Action::Generic; + +# {{{ sub new +sub new { + my $proto = shift; + my $class = ref($proto) || $proto; + my $self = {}; + bless ($self, $class); + $self->_Init(@_); + return $self; +} +# }}} + +# {{{ sub _Init +sub _Init { + my $self = shift; + my %args = ( TransactionObj => undef, + TicketObj => undef, + ScripObj => undef, + TemplateObj => undef, + Argument => undef, + Type => undef, + @_ ); + + + $self->{'Argument'} = $args{'Argument'}; + $self->{'ScripObj'} = $args{'ScripObj'}; + $self->{'TicketObj'} = $args{'TicketObj'}; + $self->{'TransactionObj'} = $args{'TransactionObj'}; + $self->{'TemplateObj'} = $args{'TemplateObj'}; + $self->{'Type'} = $args{'Type'}; +} +# }}} + +# Access Scripwide data + +# {{{ sub Argument +sub Argument { + my $self = shift; + return($self->{'Argument'}); +} +# }}} + +# {{{ sub TicketObj +sub TicketObj { + my $self = shift; + return($self->{'TicketObj'}); +} +# }}} + +# {{{ sub TransactionObj +sub TransactionObj { + my $self = shift; + return($self->{'TransactionObj'}); +} +# }}} + +# {{{ sub TemplateObj +sub TemplateObj { + my $self = shift; + return($self->{'TemplateObj'}); +} +# }}} + +# {{{ sub Type +sub Type { + my $self = shift; + return($self->{'Type'}); +} +# }}} + + +# Scrip methods + +#Do what we need to do and send it out. + +# {{{ sub Commit +sub Commit { + my $self = shift; + return(0,"Commit Stubbed"); +} +# }}} + + +#What does this type of Action does + +# {{{ sub Describe +sub Describe { + my $self = shift; + return ("No description for " . ref $self); +} +# }}} + + +#Parse the templates, get things ready to go. + +# {{{ sub Prepare +sub Prepare { + my $self = shift; + return (0,"Prepare Stubbed"); +} +# }}} + + +#If this rule applies to this transaction, return true. + +# {{{ sub IsApplicable +sub IsApplicable { + my $self = shift; + return(undef); +} +# }}} + +# {{{ sub DESTROY +sub DESTROY { + my $self = shift; + + # We need to clean up all the references that might maybe get + # oddly circular + $self->{'TemplateObj'} =undef + $self->{'TicketObj'} = undef; + $self->{'TransactionObj'} = undef; + $self->{'ScripObj'} = undef; + + + +} + +# }}} +1; diff --git a/rt/lib/RT/Action/Notify.pm b/rt/lib/RT/Action/Notify.pm new file mode 100755 index 000000000..6dca4fd41 --- /dev/null +++ b/rt/lib/RT/Action/Notify.pm @@ -0,0 +1,99 @@ +#$Header: /home/cvs/cvsroot/freeside/rt/lib/RT/Action/Notify.pm,v 1.1 2002-08-12 06:17:07 ivan Exp $ + +package RT::Action::Notify; +require RT::Action::SendEmail; +@ISA = qw(RT::Action::SendEmail); + +# {{{ sub SetRecipients + +=head2 SetRecipients + +Sets the recipients of this meesage to Owner, Requestor, AdminCc, Cc or All. +Explicitly B<does not> notify the creator of the transaction. + +=cut + +sub SetRecipients { + my $self = shift; + + $arg = $self->Argument; + + $arg =~ s/\bAll\b/Owner,Requestor,AdminCc,Cc/; + + my ( @To, @PseudoTo, @Cc, @Bcc ); + + + if ($arg =~ /\bOtherRecipients\b/) { + if ($self->TransactionObj->Message->First) { + push (@Cc, $self->TransactionObj->Message->First->GetHeader('RT-Send-Cc')); + push (@Bcc, $self->TransactionObj->Message->First->GetHeader('RT-Send-Bcc')); + } + } + + if ( $arg =~ /\bRequestor\b/ ) { + push ( @To, @{ $self->TicketObj->Requestors->Emails } ); + } + + + + if ( $arg =~ /\bCc\b/ ) { + + #If we have a To, make the Ccs, Ccs, otherwise, promote them to To + if (@To) { + push ( @Cc, @{ $self->TicketObj->Cc->Emails } ); + push ( @Cc, @{ $self->TicketObj->QueueObj->Cc->Emails } ); + } + else { + push ( @Cc, @{ $self->TicketObj->Cc->Emails } ); + push ( @To, @{ $self->TicketObj->QueueObj->Cc->Emails } ); + } + } + + if ( ( $arg =~ /\bOwner\b/ ) + && ( $self->TicketObj->OwnerObj->id != $RT::Nobody->id ) ) + { + + # If we're not sending to Ccs or requestors, + # then the Owner can be the To. + if (@To) { + push ( @Bcc, $self->TicketObj->OwnerObj->EmailAddress ); + } + else { + push ( @To, $self->TicketObj->OwnerObj->EmailAddress ); + } + + } + + if ( $arg =~ /\bAdminCc\b/ ) { + push ( @Bcc, @{ $self->TicketObj->AdminCc->Emails } ); + push ( @Bcc, @{ $self->TicketObj->QueueObj->AdminCc->Emails } ); + } + + if ($RT::UseFriendlyToLine) { + unless (@To) { + push ( @PseudoTo, + "\"$arg of $RT::rtname Ticket #" + . $self->TicketObj->id . "\":;" ); + } + } + + my $creator = $self->TransactionObj->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. + + $RT::Logger->debug("$self: To is ".join(",",@To)); + $RT::Logger->debug("$self: Cc is ".join(",",@Cc)); + $RT::Logger->debug("$self: Bcc is ".join(",",@Bcc)); + + @{ $self->{'To'} } = grep ( !/^$creator$/, @To ); + @{ $self->{'Cc'} } = grep ( !/^$creator$/, @Cc ); + @{ $self->{'Bcc'} } = grep ( !/^$creator$/, @Bcc ); + @{ $self->{'PseudoTo'} } = @PseudoTo; + return (1); + +} + +# }}} + +1; diff --git a/rt/lib/RT/Action/NotifyAsComment.pm b/rt/lib/RT/Action/NotifyAsComment.pm new file mode 100755 index 000000000..c72bfff13 --- /dev/null +++ b/rt/lib/RT/Action/NotifyAsComment.pm @@ -0,0 +1,25 @@ +#$Header: /home/cvs/cvsroot/freeside/rt/lib/RT/Action/NotifyAsComment.pm,v 1.1 2002-08-12 06:17:07 ivan Exp $ + +package RT::Action::NotifyAsComment; +require RT::Action::Notify; +@ISA = qw(RT::Action::Notify); + + +=head2 SetReturnAddress + +Tell SendEmail that this message should come out as a comment. +Calls SUPER::SetReturnAddress. + +=cut + +sub SetReturnAddress { + my $self = shift; + + # Tell RT::Action::SendEmail that this should come + # from the relevant comment email address. + $self->{'comment'} = 1; + + return($self->SUPER::SetReturnAddress(is_comment => 1)); +} +1; + diff --git a/rt/lib/RT/Action/OpenDependent.pm b/rt/lib/RT/Action/OpenDependent.pm new file mode 100644 index 000000000..b271e4709 --- /dev/null +++ b/rt/lib/RT/Action/OpenDependent.pm @@ -0,0 +1,55 @@ +# $Header: /home/cvs/cvsroot/freeside/rt/lib/RT/Action/Attic/OpenDependent.pm,v 1.1 2002-08-12 06:17:07 ivan Exp $ +# This Action will open the BASE if a dependent is resolved. + +package RT::Action::OpenDependent; +require RT::Action::Generic; +require RT::Links; +@ISA=qw(RT::Action::Generic); + +#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 (ref $self . " will stall a [local] BASE if it's open and a dependency link is created."); +} +# }}} + + +# {{{ 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 => 'DependsOn'); + $Links->Limit(FIELD => 'Target', VALUE => $self->TicketObj->id); + + while (my $Link=$Links->Next()) { + next unless $Link->BaseIsLocal; + my $base=RT::Ticket->new($self->TicketObj->CurrentUser); + # Todo: Only work if Base is a plain ticket num: + $base->Load($Link->Base); + $base->Open if $base->Status eq 'stalled'; + } +} + + +# Applicability checked in Commit. + +# {{{ sub IsApplicable +sub IsApplicable { + my $self = shift; + 1; + return 1; +} +# }}} + +1; diff --git a/rt/lib/RT/Action/ResolveMembers.pm b/rt/lib/RT/Action/ResolveMembers.pm new file mode 100644 index 000000000..00547ebe8 --- /dev/null +++ b/rt/lib/RT/Action/ResolveMembers.pm @@ -0,0 +1,57 @@ +# This Action will resolve all members of a resolved group ticket + +package RT::Action::ResolveMembers; +require RT::Action::Generic; +require RT::Links; +@ISA=qw(RT::Action::Generic); + +#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 (ref $self . " will resolve all members of a resolved group ticket."); +} +# }}} + + +# {{{ 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->BaseIsLocal; + 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; +} +# }}} + +1; + diff --git a/rt/lib/RT/Action/SendEmail.pm b/rt/lib/RT/Action/SendEmail.pm new file mode 100755 index 000000000..e3abb1154 --- /dev/null +++ b/rt/lib/RT/Action/SendEmail.pm @@ -0,0 +1,468 @@ +# $Header: /home/cvs/cvsroot/freeside/rt/lib/RT/Action/SendEmail.pm,v 1.1 2002-08-12 06:17:07 ivan Exp $ +# Copyright 1996-2002 Jesse Vincent <jesse@bestpractical.com> +# Portions Copyright 2000 Tobias Brox <tobix@cpan.org> +# Released under the terms of version 2 of the GNU Public License + +package RT::Action::SendEmail; +require RT::Action::Generic; + +@ISA = qw(RT::Action::Generic); + + +=head1 NAME + + RT::Action::SendEmail - An Action which users can use to send mail + or can subclassed for more specialized mail sending behavior. + RT::Action::AutoReply is a good example subclass. + + +=head1 SYNOPSIS + + require RT::Action::SendEmail; + @ISA = qw(RT::Action::SendEmail); + + +=head1 DESCRIPTION + +Basically, you create another module RT::Action::YourAction which ISA +RT::Action::SendEmail. + +If you want to set the recipients of the mail to something other than +the addresses mentioned in the To, Cc, Bcc and headers in +the template, you should subclass RT::Action::SendEmail and override +either the SetRecipients method or the SetTo, SetCc, etc methods (see +the comments for the SetRecipients sub). + + +=begin testing + +ok (require RT::TestHarness); +ok (require RT::Action::SendEmail); + +=end testing + + +=head1 AUTHOR + +Jesse Vincent <jesse@bestpractical.com> and Tobias Brox <tobix@cpan.org> + +=head1 SEE ALSO + +perl(1). + +=cut + +# {{{ Scrip methods (_Init, Commit, Prepare, IsApplicable) + +# {{{ sub _Init +# We use _Init from RT::Action +# }}} + +# {{{ sub Commit +#Do what we need to do and send it out. +sub Commit { + my $self = shift; + #send the email + + # If there are no recipients, don't try to send the message. + # If the transaction has content and has the header RT-Squelch-Replies-To + + if (defined $self->TransactionObj->Message->First()) { + my $headers = $self->TransactionObj->Message->First->Headers(); + + if ($headers =~ /^RT-Squelch-Replies-To: (.*?)$/si) { + my @blacklist = split(/,/,$1); + + # Cycle through the people we're sending to and pull out anyone on the + # system blacklist + + foreach my $person_to_yank (@blacklist) { + $person_to_yank =~ s/\s//g; + @{$self->{'To'}} = grep (!/^$person_to_yank$/, @{$self->{'To'}}); + @{$self->{'Cc'}} = grep (!/^$person_to_yank$/, @{$self->{'Cc'}}); + @{$self->{'Bcc'}} = grep (!/^$person_to_yank$/, @{$self->{'Bcc'}}); + } + } + } + + # 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. + + $self->SetHeader('To', join(',', @{$self->{'To'}})) + if (@{$self->{'To'}}); + $self->SetHeader('Cc', join(',' , @{$self->{'Cc'}})) + if (@{$self->{'Cc'}}); + $self->SetHeader('Bcc', join(',', @{$self->{'Bcc'}})) + if (@{$self->{'Bcc'}});; + + my $MIMEObj = $self->TemplateObj->MIMEObj; + + + $MIMEObj->make_singlepart; + + + #If we don't have any recipients to send to, don't send a message; + unless ($MIMEObj->head->get('To') || + $MIMEObj->head->get('Cc') || + $MIMEObj->head->get('Bcc') ) { + $RT::Logger->debug("$self: No recipients found. Not sending.\n"); + return(1); + } + + # PseudoTo (fake to headers) shouldn't get matched for message recipients. + # If we don't have any 'To' header, drop in the pseudo-to header. + + $self->SetHeader('To', join(',', @{$self->{'PseudoTo'}})) + if ( (@{$self->{'PseudoTo'}}) and (! $MIMEObj->head->get('To'))); + + if ($RT::MailCommand eq 'sendmailpipe') { + open (MAIL, "|$RT::SendmailPath $RT::SendmailArguments") || return(0); + print MAIL $MIMEObj->as_string; + close(MAIL); + } + else { + unless ($MIMEObj->send($RT::MailCommand, $RT::MailParams)) { + $RT::Logger->crit("$self: Could not send mail for ". + $self->TransactionObj . "\n"); + return(0); + } + } + + return (1); + +} +# }}} + +# {{{ sub Prepare + +sub Prepare { + my $self = shift; + + # This actually populates the MIME::Entity fields in the Template Object + + unless ($self->TemplateObj) { + $RT::Logger->warning("No template object handed to $self\n"); + } + + unless ($self->TransactionObj) { + $RT::Logger->warning("No transaction object handed to $self\n"); + + } + + unless ($self->TicketObj) { + $RT::Logger->warning("No ticket object handed to $self\n"); + + } + + + $self->TemplateObj->Parse(Argument => $self->Argument, + TicketObj => $self->TicketObj, + TransactionObj => $self->TransactionObj); + + # Header + + $self->SetSubject(); + + $self->SetSubjectToken(); + + $self->SetRecipients(); + + $self->SetReturnAddress(); + + $self->SetRTSpecialHeaders(); + + return 1; + +} + +# }}} + +# }}} + +# {{{ Deal with message headers (Set* subs, designed for easy overriding) + +# {{{ sub SetRTSpecialHeaders + +# This routine adds all the random headers that RT wants in a mail message +# that don't matter much to anybody else. + +sub SetRTSpecialHeaders { + my $self = shift; + + $self->SetReferences(); + + $self->SetMessageID(); + + $self->SetPrecedence(); + + $self->SetHeader('X-RT-Loop-Prevention', $RT::rtname); + $self->SetHeader('RT-Ticket', $RT::rtname. " #".$self->TicketObj->id()); + $self->SetHeader + ('Managed-by',"RT $RT::VERSION (http://bestpractical.com/rt/)"); + + $self->SetHeader('RT-Originator', $self->TransactionObj->CreatorObj->EmailAddress); + return(); + +} + + + +# {{{ sub SetReferences + +=head2 SetReferences + + # This routine will set the References: and In-Reply-To headers, +# autopopulating it with all the correspondence on this ticket so +# far. This should make RT responses threadable. + +=cut + +sub SetReferences { + my $self = shift; + + # TODO: this one is broken. What is this email really a reply to? + # If it's a reply to an incoming message, we'll need to use the + # actual message-id from the appropriate Attachment object. For + # incoming mails, we would like to preserve the In-Reply-To and/or + # References. + + $self->SetHeader + ('In-Reply-To', "<rt-".$self->TicketObj->id(). + "\@".$RT::rtname.">"); + + + # TODO We should always add References headers for all message-ids + # of previous messages related to this ticket. +} + +# }}} + +# {{{ sub SetMessageID + +# Without this one, threading won't work very nice in email agents. +# Anyway, I'm not really sure it's that healthy if we need to send +# several separate/different emails about the same transaction. + +sub SetMessageID { + my $self = shift; + + # TODO this one might be sort of broken. If we have several scrips +++ + # sending several emails to several different persons, we need to + # pull out different message-ids. I'd suggest message ids like + # "rt-ticket#-transaction#-scrip#-receipient#" + + $self->SetHeader + ('Message-ID', "<rt-".$self->TicketObj->id(). + "-". + $self->TransactionObj->id()."." .rand(20) . "\@".$RT::Organization.">") + unless $self->TemplateObj->MIMEObj->head->get('Message-ID'); +} + + +# }}} + +# }}} + +# {{{ sub SetReturnAddress + +sub SetReturnAddress { + + my $self = shift; + my %args = ( is_comment => 0, + @_ ); + + # From and Reply-To + # $args{is_comment} should be set if the comment address is to be used. + my $replyto; + + if ($args{'is_comment'}) { + $replyto = $self->TicketObj->QueueObj->CommentAddress || + $RT::CommentAddress; + } + else { + $replyto = $self->TicketObj->QueueObj->CorrespondAddress || + $RT::CorrespondAddress; + } + + unless ($self->TemplateObj->MIMEObj->head->get('From')) { + my $friendly_name=$self->TransactionObj->CreatorObj->RealName; + + if ($friendly_name =~ /^\S+\@\S+$/) { # A "bare" mail address + $friendly_name =~ s/"/\\"/g; + $friendly_name = qq|"$friendly_name"|; + } + + + # TODO: this "via RT" should really be site-configurable. + $self->SetHeader('From', "\"$friendly_name via RT\" <$replyto>"); + } + + unless ($self->TemplateObj->MIMEObj->head->get('Reply-To')) { + $self->SetHeader('Reply-To', "$replyto"); + } + +} + +# }}} + +# {{{ sub SetHeader + +sub SetHeader { + my $self = shift; + my $field = shift; + my $val = shift; + + chomp $val; + chomp $field; + $self->TemplateObj->MIMEObj->head->fold_length($field,10000); + $self->TemplateObj->MIMEObj->head->add($field, $val); + return $self->TemplateObj->MIMEObj->head->get($field); +} + +# }}} + +# {{{ sub SetRecipients + +=head2 SetRecipients + +Dummy method to be overriden by subclasses which want to set the recipients. + +=cut + +sub SetRecipients { + my $self = shift; + return(); +} + +# }}} + +# {{{ sub SetTo + +sub SetTo { + my $self=shift; + my $addresses = shift; + return $self->SetHeader('To',$addresses); +} +# }}} + +# {{{ sub SetCc +=head2 SetCc + +Takes a string that is the addresses you want to Cc + +=cut + +sub SetCc { + my $self=shift; + my $addresses = shift; + + return $self->SetHeader('Cc', $addresses); +} +# }}} + +# {{{ sub SetBcc + +=head2 SetBcc + +Takes a string that is the addresses you want to Bcc + +=cut +sub SetBcc { + my $self=shift; + my $addresses = shift; + + return $self->SetHeader('Bcc', $addresses); +} + +# }}} + +# {{{ sub SetPrecedence + +sub SetPrecedence { + my $self = shift; + + unless ($self->TemplateObj->MIMEObj->head->get("Precedence")) { + $self->SetHeader('Precedence', "bulk"); + } +} + +# }}} + +# {{{ sub SetSubject + +=head2 SetSubject + +This routine sets the subject. it does not add the rt tag. that gets done elsewhere +If $self->{'Subject'} is already defined, it uses that. otherwise, it tries to get +the transaction's subject. + +=cut + +sub SetSubject { + my $self = shift; + unless ($self->TemplateObj->MIMEObj->head->get('Subject')) { + my $message=$self->TransactionObj->Message; + my $ticket=$self->TicketObj->Id; + + my $subject; + + if ($self->{'Subject'}) { + $subject = $self->{'Subject'}; + } + elsif (($message->First()) && + ($message->First->Headers)) { + $header = $message->First->Headers(); + $header =~ s/\n\s+/ /g; + if ( $header =~ /^Subject: (.*?)$/m ) { + $subject = $1; + } + else { + $subject = $self->TicketObj->Subject(); + } + + } + else { + $subject = $self->TicketObj->Subject(); + } + + $subject =~ s/(\r\n|\n|\s)/ /gi; + + chomp $subject; + $self->SetHeader('Subject',$subject); + + } + return($subject); +} +# }}} + +# {{{ sub SetSubjectToken + +=head2 SetSubjectToken + + This routine fixes the RT tag in the subject. It's unlikely that you want to overwrite this. + +=cut + +sub SetSubjectToken { + my $self=shift; + my $tag = "[$RT::rtname #".$self->TicketObj->id."]"; + my $sub = $self->TemplateObj->MIMEObj->head->get('Subject'); + unless ($sub =~ /\Q$tag\E/) { + $sub =~ s/(\r\n|\n|\s)/ /gi; + chomp $sub; + $self->TemplateObj->MIMEObj->head->replace('Subject', "$tag $sub"); + } +} + +# }}} + +# }}} + +__END__ + +# {{{ POD + +# }}} + +1; + diff --git a/rt/lib/RT/Action/SendPasswordEmail.pm b/rt/lib/RT/Action/SendPasswordEmail.pm new file mode 100755 index 000000000..91bb3c1cb --- /dev/null +++ b/rt/lib/RT/Action/SendPasswordEmail.pm @@ -0,0 +1,170 @@ +# $Header: /home/cvs/cvsroot/freeside/rt/lib/RT/Action/Attic/SendPasswordEmail.pm,v 1.1 2002-08-12 06:17:07 ivan Exp $ +# Copyright 2001 Jesse Vincent <jesse@fsck.com> +# Released under the terms of the GNU Public License + +package RT::Action::SendPasswordEmail; +require RT::Action::Generic; + +@ISA = qw(RT::Action::Generic); + + +=head1 NAME + + RT::Action::SendGenericEmail - An Action which users can use to send mail + or can subclassed for more specialized mail sending behavior. + + + +=head1 SYNOPSIS + + require RT::Action::SendPasswordEmail; + + +=head1 DESCRIPTION + +Basically, you create another module RT::Action::YourAction which ISA +RT::Action::SendEmail. + +If you want to set the recipients of the mail to something other than +the addresses mentioned in the To, Cc, Bcc and headers in +the template, you should subclass RT::Action::SendEmail and override +either the SetRecipients method or the SetTo, SetCc, etc methods (see +the comments for the SetRecipients sub). + + +=begin testing + +ok (require RT::TestHarness); +ok (require RT::Action::SendPasswordEmail); + +=end testing + + +=head1 AUTHOR + +Jesse Vincent <jesse@bestpractical.com> + +=head1 SEE ALSO + +perl(1). + +=cut + +# {{{ Scrip methods (_Init, Commit, Prepare, IsApplicable) + +# {{{ sub Commit + +#Do what we need to do and send it out. + +sub Commit { + my $self = shift; + #send the email + + + + + + my $MIMEObj = $self->TemplateObj->MIMEObj; + + + $MIMEObj->make_singlepart; + + #If we don\'t have any recipients to send to, don\'t send a message; + unless ($MIMEObj->head->get('To')) { + $RT::Logger->debug("$self: No recipients found. Not sending.\n"); + return(1); + } + + if ($RT::MailCommand eq 'sendmailpipe') { + open (MAIL, "|$RT::SendmailPath $RT::SendmailArguments") || return(0); + print MAIL $MIMEObj->as_string; + close(MAIL); + } + else { + unless ($MIMEObj->send($RT::MailCommand, $RT::MailParams)) { + $RT::Logger->crit("$self: Could not send mail for ". + $self->TransactionObj . "\n"); + return(0); + } + } + + return (1); + +} +# }}} + +# {{{ sub Prepare + +sub Prepare { + my $self = shift; + + # This actually populates the MIME::Entity fields in the Template Object + + unless ($self->TemplateObj) { + $RT::Logger->warning("No template object handed to $self\n"); + } + + + unless ($self->TemplateObj->MIMEObj->head->get('Reply-To')) { + $self->SetHeader('Reply-To',$RT::CorrespondAddress ); + } + + + $self->SetHeader('Precedence', "bulk"); + $self->SetHeader('X-RT-Loop-Prevention', $RT::rtname); + $self->SetHeader + ('Managed-by',"Request Tracker $RT::VERSION (http://www.fsck.com/projects/rt/)"); + + $self->TemplateObj->Parse(Argument => $self->Argument); + + + return 1; +} + +# }}} + +# }}} + + +# {{{ sub SetTo + +=head2 SetTo EMAIL + +Sets this message's "To" field to EMAIL + +=cut + +sub SetTo { + my $self = shift; + my $to = shift; + $self->SetHeader('To',$to); +} + +# }}} + +# {{{ sub SetHeader + +sub SetHeader { + my $self = shift; + my $field = shift; + my $val = shift; + + chomp $val; + chomp $field; + $self->TemplateObj->MIMEObj->head->fold_length($field,10000); + $self->TemplateObj->MIMEObj->head->add($field, $val); + return $self->TemplateObj->MIMEObj->head->get($field); +} + +# }}} + + + +__END__ + +# {{{ POD + +# }}} + +1; + diff --git a/rt/lib/RT/Action/StallDependent.pm b/rt/lib/RT/Action/StallDependent.pm new file mode 100644 index 000000000..09d3448a8 --- /dev/null +++ b/rt/lib/RT/Action/StallDependent.pm @@ -0,0 +1,68 @@ +# This Action will stall the BASE if a dependency or membership link +# (according to argument) is created and if BASE is open. + +# TODO: Rename this .pm + +package RT::Action::StallDependent; +require RT::Action::Generic; +@ISA=qw|RT::Action::Generic|; + +# {{{ sub Describe +sub Describe { + my $self = shift; + return (ref $self . " will stall a [local] BASE if it's dependent [or member] of a linked up request."); +} +# }}} + + +# {{{ sub Prepare +sub Prepare { + # nothing to prepare + return 1; +} +# }}} + +sub Commit { + my $self = shift; + # Find all Dependent + my $arg=$self->Argument || "DependsOn"; + unless ($self->TransactionObj->Data =~ /^([^ ]+) $arg /) { + warn; return 0; + } + my $base_id=$1; + my $base; + if ($1 eq "THIS") { + $base=$self->TicketObj; + } else { + $base_id=&RT::Link::_IsLocal(undef, $base_id) || return 0; + $base=RT::Ticket->new($self->TicketObj->CurrentUser); + $base->Load($base_id); + } + $base->Stall if $base->Status eq 'open'; + return 0; +} + + +# {{{ sub IsApplicable + +# Only applicable if: +# 1. the link action is a dependency +# 2. BASE is a local ticket + +sub IsApplicable { + my $self = shift; + + my $arg=$self->Argument || "DependsOn"; + + # 1: + $self->TransactionObj->Data =~ /^([^ ]*) $arg / || return 0; + + # 2: + # (dirty!) + &RT::Link::_IsLocal(undef,$1) || return 0; + + return 1; +} +# }}} + +1; |