1<?php
2/*
3 * vim:set softtabstop=4 shiftwidth=4 expandtab:
4 *
5 * LICENSE: GNU Affero General Public License, version 3 (AGPL-3.0-or-later)
6 * Copyright 2001 - 2020 Ampache.org
7 *
8 * This program is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU Affero 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 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 * GNU Affero General Public License for more details.
17 *
18 * You should have received a copy of the GNU Affero General Public License
19 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
20 *
21 */
22
23declare(strict_types=0);
24
25namespace Ampache\Module\Util;
26
27use Ampache\Config\AmpConfig;
28use Ampache\Module\System\Dba;
29use PHPMailer\PHPMailer\Exception;
30use PHPMailer\PHPMailer\PHPMailer;
31
32/**
33 * This class handles the Mail
34 *
35 * @todo create setters for all properties
36 */
37final class Mailer implements MailerInterface
38{
39    // The message, recipient and from
40    public $message;
41    public $subject;
42    public $recipient;
43    public $recipient_name;
44    public $sender;
45    public $sender_name;
46
47    /**
48     * is_mail_enabled
49     *
50     * Check that the mail feature is enabled
51     * @return boolean
52     */
53    public static function is_mail_enabled()
54    {
55        if (AmpConfig::get('mail_enable') && !AmpConfig::get('demo_mode')) {
56            return true;
57        }
58
59        // by default you actually want people to set up mail first
60        return false;
61    }
62
63    /**
64     * Check that the mail feature is enabled
65     */
66    public function isMailEnabled(): bool
67    {
68        return static::is_mail_enabled();
69    }
70
71    /**
72     * validate_address
73     *
74     * Checks whether what we have looks like a valid address.
75     * @param string $address
76     * @return boolean
77     */
78    public static function validate_address($address)
79    {
80        return PHPMailer::ValidateAddress($address);
81    }
82
83    /**
84     * set_default_sender
85     *
86     * Does the config magic to figure out the "system" email sender and
87     * sets it as the sender.
88     */
89    public function set_default_sender()
90    {
91        $user = AmpConfig::get('mail_user');
92        if (!$user) {
93            $user = 'info';
94        }
95
96        $domain = AmpConfig::get('mail_domain');
97        if (!$domain) {
98            $domain = 'example.com';
99        }
100
101        $fromname = AmpConfig::get('mail_name');
102        if (!$fromname) {
103            $fromname = 'Ampache';
104        }
105
106        $this->sender      = $user . '@' . $domain;
107        $this->sender_name = $fromname;
108    } // set_default_sender
109
110    /**
111     * get_users
112     * This returns an array of userids for people who have e-mail
113     * addresses based on the passed filter
114     * @param $filter
115     * @return array
116     */
117    public static function get_users($filter)
118    {
119        switch ($filter) {
120            case 'users':
121                $sql = "SELECT * FROM `user` WHERE `access`='25' AND `email` IS NOT NULL";
122                break;
123            case 'admins':
124                $sql = "SELECT * FROM `user` WHERE `access`='100' AND `email` IS NOT NULL";
125                break;
126            case 'inactive':
127                $inactive = time() - (30 * 86400);
128                $sql      = 'SELECT * FROM `user` WHERE `last_seen` <= ? AND `email` IS NOT NULL';
129                break;
130            case 'all':
131            default:
132                $sql = "SELECT * FROM `user` WHERE `email` IS NOT NULL";
133                break;
134        } // end filter switch
135
136        $db_results = Dba::read($sql, isset($inactive) ? array($inactive) : array());
137
138        $results = array();
139
140        while ($row = Dba::fetch_assoc($db_results)) {
141            $results[] = array('id' => $row['id'], 'fullname' => $row['fullname'], 'email' => $row['email']);
142        }
143
144        return $results;
145    } // get_users
146
147    /**
148     * send
149     * This actually sends the mail, how amazing
150     * @param PHPMailer $phpmailer
151     * @return boolean
152     * @throws Exception
153     */
154    public function send($phpmailer = null)
155    {
156        $mailtype = AmpConfig::get('mail_type');
157
158        if ($phpmailer == null) {
159            $mail = new PHPMailer();
160
161            $recipient_name = $this->recipient_name;
162            if (function_exists('mb_encode_mimeheader')) {
163                $recipient_name = mb_encode_mimeheader($recipient_name);
164            }
165            $mail->AddAddress($this->recipient, $recipient_name);
166        } else {
167            $mail = $phpmailer;
168        }
169
170        $mail->CharSet  = AmpConfig::get('site_charset');
171        $mail->Encoding = 'base64';
172        $mail->From     = $this->sender;
173        $mail->Sender   = $this->sender;
174        $mail->FromName = $this->sender_name;
175        $mail->Subject  = $this->subject;
176
177        if (function_exists('mb_eregi_replace')) {
178            $this->message = mb_eregi_replace("\r\n", "\n", $this->message);
179        }
180        $mail->Body = $this->message;
181
182        $sendmail = AmpConfig::get('sendmail_path');
183        $sendmail = $sendmail ? $sendmail : '/usr/sbin/sendmail';
184        $mailhost = AmpConfig::get('mail_host');
185        $mailhost = $mailhost ? $mailhost : 'localhost';
186        $mailport = AmpConfig::get('mail_port');
187        $mailport = $mailport ? $mailport : 25;
188        $mailauth = AmpConfig::get('mail_auth');
189        $mailuser = AmpConfig::get('mail_auth_user');
190        $mailuser = $mailuser ? $mailuser : '';
191        $mailpass = AmpConfig::get('mail_auth_pass');
192        $mailpass = $mailpass ? $mailpass : '';
193
194        switch ($mailtype) {
195            case 'smtp':
196                $mail->IsSMTP();
197                $mail->Host = $mailhost;
198                $mail->Port = $mailport;
199                if ($mailauth) {
200                    $mail->SMTPAuth = true;
201                    $mail->Username = $mailuser;
202                    $mail->Password = $mailpass;
203                }
204                if ($mailsecure = AmpConfig::get('mail_secure_smtp')) {
205                    $mail->SMTPSecure = ($mailsecure == 'ssl') ? 'ssl' : 'tls';
206                }
207                break;
208            case 'sendmail':
209                $mail->IsSendmail();
210                $mail->Sendmail = $sendmail;
211                break;
212            case 'php':
213            default:
214                $mail->IsMail();
215                break;
216        }
217
218        $retval = $mail->send();
219        if ($retval === true) {
220            return true;
221        } else {
222            return false;
223        }
224    } // send
225
226    /**
227     * @param $group_name
228     * @return boolean
229     * @throws Exception
230     */
231    public function send_to_group($group_name)
232    {
233        $mail = new PHPMailer();
234
235        foreach (self::get_users($group_name) as $member) {
236            if (function_exists('mb_encode_mimeheader')) {
237                $member['fullname'] = mb_encode_mimeheader($member['fullname']);
238            }
239            $mail->AddBCC($member['email'], $member['fullname']);
240        }
241
242        return $this->send($mail);
243    }
244}
245