Bug 28729: Additions to POD
[koha.git] / Koha / Email.pm
1 package Koha::Email;
2
3 # Copyright 2014 Catalyst
4 #           2020 Theke Solutions
5 #
6 # This file is part of Koha.
7 #
8 # Koha is free software; you can redistribute it and/or modify it
9 # under the terms of the GNU General Public License as published by
10 # the Free Software Foundation; either version 3 of the License, or
11 # (at your option) any later version.
12 #
13 # Koha is distributed in the hope that it will be useful, but
14 # WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 # GNU General Public License for more details.
17 #
18 # You should have received a copy of the GNU General Public License
19 # along with Koha; if not, see <http://www.gnu.org/licenses>.
20
21 use Modern::Perl;
22
23 use Email::Address;
24 use Email::MessageID;
25 use List::Util qw( pairs );
26
27 use Koha::Exceptions;
28
29 use C4::Context;
30
31 use base qw( Email::Stuffer );
32
33 =head1 NAME
34
35 Koha::Email - A wrapper around Email::Stuffer
36
37 =head1 API
38
39 =head2 Class methods
40
41 =head3 create
42
43     my $email = Koha::Email->create(
44         {
45           [ text_body   => $text_message,
46             html_body   => $html_message,
47             body_params => $body_params ]
48             from        => $from,
49             to          => $to,
50             cc          => $cc,
51             bcc         => $bcc,
52             reply_to    => $reply_to,
53             sender      => $sender,
54             subject     => $subject,
55         }
56     );
57
58 This method creates a new Email::Stuffer object taking Koha specific configurations
59 into account.
60
61 The encoding defaults to utf-8. It can be set as part of the body_params hashref. See
62 I<Email::Stuffer> and I<Email::MIME> for more details on the available options.
63
64 Parameters:
65  - I<from> defaults to the value of the I<KohaAdminEmailAddress> system preference
66  - The I<SendAllEmailsTo> system preference overloads the I<to>, I<cc> and I<bcc> parameters
67  - I<reply_to> defaults to the value of the I<ReplytoDefault> system preference
68  - I<sender> defaults to the value of the I<ReturnpathDefault> system preference
69
70 Both I<text_body> and I<html_body> can be set later. I<body_params> will be passed if present
71 to the constructor.
72
73 =cut
74
75 sub create {
76     my ( $self, $params ) = @_;
77
78     my $args = {};
79     $args->{from} = $params->{from} || C4::Context->preference('KohaAdminEmailAddress');
80     Koha::Exceptions::BadParameter->throw(
81         error     => "Invalid 'from' parameter: " . $args->{from},
82         parameter => 'from'
83     ) unless Koha::Email->is_valid( $args->{from} );    # from is mandatory
84
85     $args->{subject} = $params->{subject} // '';
86
87     if ( C4::Context->preference('SendAllEmailsTo') ) {
88         $args->{to} = C4::Context->preference('SendAllEmailsTo');
89     }
90     else {
91         $args->{to} = $params->{to};
92     }
93
94     Koha::Exceptions::BadParameter->throw(
95         error     => "Invalid 'to' parameter: " . $args->{to},
96         parameter => 'to'
97     ) unless Koha::Email->is_valid( $args->{to} );    # to is mandatory
98
99     my $addresses = {};
100     $addresses->{reply_to} = $params->{reply_to};
101     $addresses->{reply_to} ||= C4::Context->preference('ReplytoDefault')
102         if C4::Context->preference('ReplytoDefault');
103
104     $addresses->{sender} = $params->{sender};
105     $addresses->{sender} ||= C4::Context->preference('ReturnpathDefault')
106         if C4::Context->preference('ReturnpathDefault');
107
108     unless ( C4::Context->preference('SendAllEmailsTo') ) {
109         $addresses->{cc} = $params->{cc}
110             if exists $params->{cc};
111         $addresses->{bcc} = $params->{bcc}
112             if exists $params->{bcc};
113     }
114
115     foreach my $address ( keys %{$addresses} ) {
116         Koha::Exceptions::BadParameter->throw(
117             error => "Invalid '$address' parameter: " . $addresses->{$address},
118             parameter => $address
119           )
120           if $addresses->{$address}
121           and !Koha::Email->is_valid( $addresses->{$address} );
122     }
123
124     $args->{cc} = $addresses->{cc}
125         if $addresses->{cc};
126     $args->{bcc} = $addresses->{bcc}
127         if $addresses->{bcc};
128
129     my $email = $self->SUPER::new( $args );
130
131     $email->header( 'Reply-To', $addresses->{reply_to} )
132         if $addresses->{reply_to};
133
134     $email->header( 'Sender'       => $addresses->{sender} ) if $addresses->{sender};
135     $email->header( 'Content-Type' => $params->{contenttype} ) if $params->{contenttype};
136     $email->header( 'X-Mailer'     => "Koha" );
137     $email->header( 'Message-ID'   => Email::MessageID->new->in_brackets );
138
139     if ( $params->{text_body} ) {
140         $email->text_body( $params->{text_body}, %{ $params->{body_params} } );
141     }
142     elsif ( $params->{html_body} ) {
143         $email->html_body( $params->{html_body}, %{ $params->{body_params} } );
144     }
145
146     return $email;
147 }
148
149 =head3 send_or_die
150
151     $email->send_or_die({ transport => $transport [, $args] });
152
153 Overloaded Email::Stuffer I<send_or_die> method, that takes care of Bcc and Return-path
154 handling.
155
156 Bcc is removed from the message headers, and included in the recipients list to be
157 passed to I<send_or_die>.
158
159 Return-path, 'MAIL FROM', is set to the 'Sender' email header unless an explicit 'from'
160 parameter is passed to send_or_die.  'Return-path' headers are actually set by the MTA,
161 usually using the 'MAIL FROM' information set at mail server connection time.
162
163 =cut
164
165 sub send_or_die {
166     my ( $self, $args ) = @_;
167
168     unless ( $args->{to} ) {    # don't do it if passed an explicit 'to' param
169
170         my @recipients;
171
172         my @headers = $self->email->header_str_pairs;
173         foreach my $pair ( pairs @headers ) {
174             my ( $header, $value ) = @$pair;
175             push @recipients, split (', ', $value)
176                 if grep { $_ eq $header } ('To', 'Cc', 'Bcc');
177         }
178
179         # Remove the Bcc header
180         $self->email->header_str_set('Bcc');
181
182         # Tweak $args
183         $args->{to} = \@recipients;
184     }
185
186     unless ( $args->{from} ) {    # don't do it if passed an explicit 'from' param
187         $args->{from} = $self->email->header_str('Sender');
188         $self->email->header_str_set('Sender'); # remove Sender header
189     }
190
191     $self->SUPER::send_or_die($args);
192 }
193
194 =head3 is_valid
195
196     my $is_valid = Koha::Email->is_valid($email_address);
197
198 Return true is the email address passed in parameter is valid following RFC 2822.
199
200 =cut
201
202 sub is_valid {
203     my ( $class, $email ) = @_;
204     my @addrs = Email::Address->parse($email);
205     return @addrs ? 1 : 0;
206 }
207
208 1;