summaryrefslogtreecommitdiff
path: root/LedgerSMB/Mailer.pm
blob: 4903b6299f1ad94941ef0195822a71b38798e936 (plain)
  1. =head1 NAME
  2. LedgerSMB::Mailer Mail output for LedgerSMB
  3. =head1 SYNOPSIS
  4. =head1 COPYRIGHT
  5. #====================================================================
  6. # LedgerSMB
  7. # Small Medium Business Accounting software
  8. # http://www.ledgersmb.org/
  9. #
  10. # Copyright (C) 2006
  11. # This work contains copyrighted information from a number of sources
  12. # all used with permission.
  13. #
  14. # This file contains source code included with or based on SQL-Ledger
  15. # which # is Copyright Dieter Simader and DWS Systems Inc. 2000-2005
  16. # and licensed under the GNU General Public License version 2 or, at
  17. # your option, any later version. For a full list including contact
  18. # information of contributors, maintainers, and copyright holders,
  19. # see the CONTRIBUTORS file.
  20. #
  21. # Original Copyright Notice from SQL-Ledger 2.6.17 (before the fork):
  22. # Copyright (C) 2002
  23. #
  24. # Author: DWS Systems Inc.
  25. # Web: http://www.sql-ledger.org
  26. #
  27. # Contributors:
  28. #
  29. # Original Author and copyright holder:
  30. # Dieter Simader dsmimader@sql-ledger.com
  31. #====================================================================
  32. =head1 METHODS
  33. =cut
  34. package LedgerSMB::Mailer;
  35. use warnings;
  36. use strict;
  37. use Carp;
  38. use Encode;
  39. use MIME::Lite;
  40. use LedgerSMB::Sysconfig;
  41. our $VERSION = '0.13';
  42. =head2 LedgerSMB::Mailer->new(...)
  43. Create a new Mailer object. If any arguments are passed in, a message
  44. that uses them will be automatically prepared but not sent.
  45. =cut
  46. sub new {
  47. my $type = shift;
  48. my $self = {};
  49. bless $self, $type;
  50. $self->prepare_message(@_) if @_;
  51. $self;
  52. }
  53. =head2 $mail->prepare_message(to => $to, from => $from, ...)
  54. Prepares and encodes base message for sending or adding attachments.
  55. =head3 Arguments
  56. =over
  57. =item to, from, cc, bcc
  58. Address fields for the email.
  59. =item subject
  60. The subject for the email.
  61. =item message
  62. The message body for the email.
  63. =item contenttype
  64. The conttent type for the body of the message, not for any attachments.
  65. =item notify
  66. Sets the Disposition-Notification-To header (read receipt request) for the
  67. message. This header will only be added if a from address is set.
  68. =back
  69. =cut
  70. sub prepare_message {
  71. my $self = shift;
  72. my %args = @_;
  73. # Populate message fields
  74. for my $key (keys %args) {
  75. $self->{$key} = $args{$key};
  76. }
  77. my $domain = $self->{from};
  78. $domain =~ s/(.*?\@|>)//g;
  79. my $boundary = time;
  80. $boundary = "LSMB-$boundary";
  81. my $msg_id = "$boundary\@$domain";
  82. $self->{contenttype} = "text/plain" unless $self->{contenttype};
  83. for (qw(from to cc bcc subject)) {
  84. next unless $self->{$_};
  85. $self->{$_} =~ s/(\/|\\|\$)//g;
  86. $self->{$_} =~ s/([\n\r\f])/$1 /g;
  87. }
  88. $self->{_message} = MIME::Lite->new(
  89. 'From' => $self->{from},
  90. 'To' => $self->{to},
  91. 'Cc' => $self->{cc},
  92. 'Bcc' => $self->{bcc},
  93. 'Subject' => Encode::encode('MIME-Header', $self->{subject}),
  94. 'Type' => 'TEXT',
  95. 'Data' => Encode::encode_utf8($self->{message}),
  96. 'Encoding' => '8bit',
  97. 'Message-ID' => $msg_id,
  98. );
  99. $self->{_message}->attr( 'Content-Type' => $self->{contenttype} );
  100. $self->{_message}->attr( 'Content-Type.charset' => 'UTF-8' ) if
  101. $self->{contenttype} =~ m#^text/#;
  102. # Annoy people with read receipt requests
  103. $self->{_message}->add( 'Disposition-Notification-To' => $self->{from} )
  104. if $self->{notify};
  105. $self->{_message}->binmode(':utf8');
  106. }
  107. =head2 $mail->attach(data => $data, filename => $name, strip => $strip)
  108. Add an attachment to the prepared message. If $data is specified, use the
  109. value of that variable as the attachment value, otherwise attach the file
  110. given by $name. If both a filename and data are given, the data is attached
  111. and given the name from filename.
  112. $strip is an optional string to remove from the filename send with the
  113. attachment.
  114. =cut
  115. sub attach {
  116. my $self = shift;
  117. my %args = @_;
  118. carp "Message not prepared" unless ref $self->{_message};
  119. if (defined $args{filename}) {
  120. if (!$args{filename}){
  121. carp "Invalid filename provided";
  122. } elsif (!defined $args{data} and !(-f $args{filename} and -r $args{filename})){
  123. carp "Cannot access file: $args{filename}";
  124. }
  125. } else {
  126. carp "No attachement supplied" unless defined $args{data};
  127. }
  128. # strip path from output name
  129. my $file;
  130. if ($args{filename}) {
  131. my $strip = quotemeta $args{strip};
  132. $file = $args{filename};
  133. $file =~ s/(.*\/|$strip)//g;
  134. }
  135. # handle both string and file types of input
  136. my @data;
  137. if (defined $args{data}) {
  138. @data = ('Data', $args{data});
  139. } else {
  140. @data = ('Path', $args{filename});
  141. }
  142. $self->{_message}->attach(
  143. 'Type' => $args{mimetype},
  144. 'Filename' => $file,
  145. 'Disposition' => 'attachment',
  146. @data,
  147. );
  148. }
  149. =head2 $mail->send
  150. Sends a prepared message using the method configured in ledgersmb.conf.
  151. =cut
  152. sub send {
  153. my $self = shift;
  154. carp "Message not prepared" unless ref $self->{_message};
  155. # SC: Set the X-Mailer header here so that it will be the last
  156. # header set. This ensures that MIME::Lite will not rewrite
  157. # it during the preparation of the message.
  158. $self->{_message}->replace( 'X-Mailer' => "LedgerSMB::Mailer $VERSION" );
  159. if ( ${LedgerSMB::Sysconfig::smtphost} ) {
  160. $self->{_message}->send(
  161. 'smtp',
  162. ${LedgerSMB::Sysconfig::smtphost},
  163. Timeout => ${LedgerSMB::Sysconfig::smtptimeout}
  164. ) || return $!;
  165. } else {
  166. $self->{_message}->send(
  167. 'sendmail',
  168. ${LedgerSMB::Sysconfig::sendmail}
  169. ) || return $!;
  170. }
  171. }
  172. 1;