Passed
Push — master ( 145306...a46cb4 )
by Michael
17:35 queued 09:16
created

XoopsMultiMailer   A

Complexity

Total Complexity 9

Size/Duplication

Total Lines 158
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 46
c 1
b 0
f 0
dl 0
loc 158
rs 10
wmc 9

2 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 32 4
A sendmailSend() 0 21 5
1
<?php
2
/**
3
 * Xoops MultiMailer Base Class
4
 *
5
 * You may not change or alter any portion of this comment or credits
6
 * of supporting developers from this source code or any supporting source code
7
 * which is considered copyrighted (c) material of the original comment or credit authors.
8
 * This program is distributed in the hope that it will be useful,
9
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11
 *
12
 * @copyright       (c) 2000-2025 XOOPS Project (https://xoops.org)
13
 * @license             GNU GPL 2 (https://www.gnu.org/licenses/gpl-2.0.html)
14
 * @package             Kernel
15
 * @subpackage          mail
16
 * @since               2.0.0
17
 * @author              Author: Jochen Büînagel ([email protected])
18
 */
19
20
/**
21
 *
22
 * @package    class
23
 * @subpackage mail
24
 * @filesource
25
 * @author     Jochen Büînagel <[email protected]>
26
 */
27
28
defined('XOOPS_ROOT_PATH') || exit('Restricted access');
29
30
use Xmf\Mail\SendmailRunner;
0 ignored issues
show
Bug introduced by
The type Xmf\Mail\SendmailRunner was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
31
use PHPMailer\PHPMailer\PHPMailer;
32
33
// bridge class for PhpMailer 6.x PHPMailer\PHPMailer\Exception
34
35
/**
36
 * load the base class
37
 */
38
39
40
/**
41
 * Mailer Class.
42
 *
43
 * At the moment, this does nothing but send email through PHP "mail()" function,
44
 * but it has the ability to do much more.
45
 *
46
 * If you have problems sending mail with "mail()", you can edit the member variables
47
 * to suit your setting. Later this will be possible through the admin panel.
48
 *
49
 * @todo       Make a page in the admin panel for setting mailer preferences.
50
 * @package    class
51
 * @subpackage mail
52
 * @author     Jochen Buennagel <[email protected]>
53
 */
54
class XoopsMultiMailer extends PHPMailer
55
{
56
    /**
57
     * 'from' address
58
     *
59
     * @var string
60
     * @access private
61
     */
62
    public $From = '';
63
64
    /**
65
     * 'from' name
66
     *
67
     * @var string
68
     * @access private
69
     */
70
    public $FromName = '';
71
72
    // can be 'smtp', 'sendmail', or 'mail'
73
    /**
74
     * Method to be used when sending the mail.
75
     *
76
     * This can be:
77
     * <li>mail (standard PHP function 'mail()') (default)
78
     * <li>smtp    (send through any SMTP server, SMTPAuth is supported.
79
     * You must set {@link $Host}, for SMTPAuth also {@link $SMTPAuth},
80
     * {@link $Username}, and {@link $Password}.)
81
     * <li>sendmail (manually set the path to your sendmail program
82
     * to something different than 'mail()' uses in {@link $Sendmail})
83
     *
84
     * @var string
85
     * @access private
86
     */
87
    public $Mailer = 'mail';
88
89
    /**
90
     * set if $Mailer is 'sendmail'
91
     *
92
     * Only used if {@link $Mailer} is set to 'sendmail'.
93
     * Contains the full path to your sendmail program or replacement.
94
     *
95
     * @var string
96
     * @access private
97
     */
98
    public $Sendmail = '/usr/sbin/sendmail';
99
100
    /**
101
     * SMTP Host.
102
     *
103
     * Only used if {@link $Mailer} is set to 'smtp'
104
     *
105
     * @var string
106
     * @access private
107
     */
108
    public $Host = '';
109
110
    /**
111
     * Does your SMTP host require SMTPAuth authentication?
112
     *
113
     * @var boolean
114
     * @access private
115
     */
116
    public $SMTPAuth = false;
117
118
    /**
119
     * Username for authentication with your SMTP host.
120
     *
121
     * Only used if {@link $Mailer} is 'smtp' and {@link $SMTPAuth} is TRUE
122
     *
123
     * @var string
124
     * @access private
125
     */
126
    public $Username = '';
127
128
    /**
129
     * Password for SMTPAuth.
130
     *
131
     * Only used if {@link $Mailer} is 'smtp' and {@link $SMTPAuth} is TRUE
132
     *
133
     * @var string
134
     * @access private
135
     */
136
    public $Password = '';
137
138
    /**
139
     * Constructor
140
     *
141
     * @access public
142
     */
143
    public function __construct()
144
    {
145
        parent::__construct(true); // Enable exceptions in PHPMailer
146
147
        /** @var XoopsConfigHandler $config_handler */
148
        $config_handler    = xoops_getHandler('config');
149
        $xoopsMailerConfig = $config_handler->getConfigsByCat(XOOPS_CONF_MAILER);
150
        $this->From        = $xoopsMailerConfig['from'];
151
        if ('' == $this->From) {
152
            $this->From = $GLOBALS['xoopsConfig']['adminmail'];
153
        }
154
        $this->Sender = $this->From;
155
        if ('smtpauth' === $xoopsMailerConfig['mailmethod']) {
156
            $this->Mailer   = 'smtp';
157
            $this->SMTPAuth = true;
158
            // TODO: change value type of xoopsConfig 'smtphost' from array to text
159
            $this->Host     = implode(';', $xoopsMailerConfig['smtphost']);
160
            $this->Username = $xoopsMailerConfig['smtpuser'];
161
            $this->Password = $xoopsMailerConfig['smtppass'];
162
        } else {
163
            $this->Mailer   = $xoopsMailerConfig['mailmethod'];
164
            $this->SMTPAuth = false;
165
            $this->Sendmail = $xoopsMailerConfig['sendmailpath'];
166
            $this->Host     = implode(';', $xoopsMailerConfig['smtphost']);
167
        }
168
        $this->CharSet = strtolower(_CHARSET);
169
        $xoopsLanguage = preg_replace('/[^a-zA-Z0-9_-]/', '', $GLOBALS['xoopsConfig']['language']);
170
        if (file_exists(XOOPS_ROOT_PATH . '/language/' . $xoopsLanguage . '/phpmailer.php')) {
171
            include XOOPS_ROOT_PATH . '/language/' . $xoopsLanguage . '/phpmailer.php';
172
            $this->language = $PHPMAILER_LANG;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $PHPMAILER_LANG seems to be never defined.
Loading history...
173
        } else {
174
            $this->setLanguage('en', XOOPS_ROOT_PATH . '/class/mail/phpmailer/language/');
175
        }
176
        //$this->pluginDir = XOOPS_ROOT_PATH . '/class/mail/phpmailer/';
177
    }
178
179
    /**
180
     * Overrides PHPMailer's protected sendmailSend method to use XOOPS' hardened runner for sendmail delivery.
181
     *
182
     * Security enhancement: Instead of directly invoking the sendmail binary, this method uses XOOPS' SendmailRunner,
183
     * which applies additional security checks and policies to the delivery process.
184
     *
185
     * @param string $header RFC 5322-compliant message headers, with LF line endings.
186
     * @param string $body   Message body, with LF line endings.
187
     *                       Both parameters are expected to be formatted as provided by PHPMailer.
188
     * @return bool True on successful delivery, false otherwise.
189
     * @throws PHPMailer\PHPMailer\Exception when exceptions are enabled and delivery fails.
190
     */
191
    protected function sendmailSend($header, $body): bool
192
    {
193
        // Build a complete RFC 5322 message. PHPMailer gives LF; runner normalizes to CRLF.
194
        $rfc822 = rtrim($header, "\r\n") . "\n\n" . $body;
195
196
        // XOOPS config already set this in ctor from preferences:
197
        $path = (string)$this->Sendmail;
198
        // Prefer Sender (envelope-from), fall back to From if Sender is empty:
199
        $envelopeFrom = $this->Sender ?: $this->From ?: null;
200
201
        try {
202
            $runner = new SendmailRunner();           // optionally pass a custom allowlist/policy
203
            $runner->deliver($path, $rfc822, $envelopeFrom);
204
            return true;
205
        } catch (\RuntimeException $e) {
206
            // Preserve PHPMailer’s error/exception contract
207
            if ($this->exceptions) {
208
                throw new \PHPMailer\PHPMailer\Exception($e->getMessage(), 0, $e);
209
            }
210
            $this->setError($e->getMessage());
211
            return false;
212
        }
213
    }
214
215
}
216