Passed
Push — master ( bbacda...9d4008 )
by Marcus
43:43
created

src/POP3.php (3 issues)

mismatching argument types.

Documentation Minor

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
/**
3
 * PHPMailer POP-Before-SMTP Authentication Class.
4
 * PHP Version 5.5
5
 *
6
 * @package   PHPMailer
7
 * @see       https://github.com/PHPMailer/PHPMailer/ The PHPMailer GitHub project
8
 * @author    Marcus Bointon (Synchro/coolbru) <[email protected]>
9
 * @author    Jim Jagielski (jimjag) <[email protected]>
10
 * @author    Andy Prevost (codeworxtech) <[email protected]>
11
 * @author    Brent R. Matzelle (original founder)
12
 * @copyright 2012 - 2016 Marcus Bointon
13
 * @copyright 2010 - 2012 Jim Jagielski
14
 * @copyright 2004 - 2009 Andy Prevost
15
 * @license   http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
16
 * @note      This program is distributed in the hope that it will be useful - WITHOUT
17
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18
 * FITNESS FOR A PARTICULAR PURPOSE.
19
 */
20
21
namespace PHPMailer\PHPMailer;
22
23
/**
24
 * PHPMailer POP-Before-SMTP Authentication Class.
25
 * Specifically for PHPMailer to use for RFC1939 POP-before-SMTP authentication.
26
 * 1) This class does not support APOP authentication.
27
 * 2) Opening and closing lots of POP3 connections can be quite slow. If you need
28
 *   to send a batch of emails then just perform the authentication once at the start,
29
 *   and then loop through your mail sending script. Providing this process doesn't
30
 *   take longer than the verification period lasts on your POP3 server, you should be fine.
31
 * 3) This is really ancient technology; you should only need to use it to talk to very old systems.
32
 * 4) This POP3 class is deliberately lightweight and incomplete, and implements just
33
 *   enough to do authentication.
34
 *   If you want a more complete class there are other POP3 classes for PHP available.
35
 *
36
 * @package PHPMailer
37
 * @author  Richard Davey (original author) <[email protected]>
38
 * @author  Marcus Bointon (Synchro/coolbru) <[email protected]>
39
 * @author  Jim Jagielski (jimjag) <[email protected]>
40
 * @author  Andy Prevost (codeworxtech) <[email protected]>
41
 */
42
class POP3
43
{
44
    /**
45
     * The POP3 PHPMailer Version number.
46
     *
47
     * @var string
48
     */
49
    const VERSION = '6.0.0';
50
51
    /**
52
     * Default POP3 port number.
53
     *
54
     * @var integer
55
     */
56
    const DEFAULT_PORT = 110;
57
58
    /**
59
     * Default timeout in seconds.
60
     *
61
     * @var integer
62
     */
63
    const DEFAULT_TIMEOUT = 30;
64
65
    /**
66
     * Debug display level.
67
     * Options: 0 = no, 1+ = yes
68
     *
69
     * @var integer
70
     */
71
    public $do_debug = 0;
72
73
    /**
74
     * POP3 mail server hostname.
75
     *
76
     * @var string
77
     */
78
    public $host;
79
80
    /**
81
     * POP3 port number.
82
     *
83
     * @var integer
84
     */
85
    public $port;
86
87
    /**
88
     * POP3 Timeout Value in seconds.
89
     *
90
     * @var integer
91
     */
92
    public $tval;
93
94
    /**
95
     * POP3 username
96
     *
97
     * @var string
98
     */
99
    public $username;
100
101
    /**
102
     * POP3 password.
103
     *
104
     * @var string
105
     */
106
    public $password;
107
108
    /**
109
     * Resource handle for the POP3 connection socket.
110
     *
111
     * @var resource
112
     */
113
    protected $pop_conn;
114
115
    /**
116
     * Are we connected?
117
     *
118
     * @var boolean
119
     */
120
    protected $connected = false;
121
122
    /**
123
     * Error container.
124
     *
125
     * @var array
126
     */
127
    protected $errors = [];
128
129
    /**
130
     * Line break constant
131
     */
132
    const LE = "\r\n";
133
134
    /**
135
     * Simple static wrapper for all-in-one POP before SMTP
136
     *
137
     * @param string $host
138
     * @param integer|boolean $port The port number to connect to
139
     * @param integer|boolean $timeout The timeout value
140
     * @param string $username
141
     * @param string $password
142
     * @param integer $debug_level
143
     *
144
     * @return boolean
145
     */
146
    public static function popBeforeSmtp(
147
        $host,
148
        $port = false,
149
        $timeout = false,
150
        $username = '',
151
        $password = '',
152
        $debug_level = 0
153
    ) {
154
        $pop = new POP3;
155
        return $pop->authorise($host, $port, $timeout, $username, $password, $debug_level);
156
    }
157
158
    /**
159
     * Authenticate with a POP3 server.
160
     * A connect, login, disconnect sequence
161
     * appropriate for POP-before SMTP authorisation.
162
     *
163
     * @param string $host The hostname to connect to
164
     * @param integer|boolean $port The port number to connect to
165
     * @param integer|boolean $timeout The timeout value
166
     * @param string $username
167
     * @param string $password
168
     * @param integer $debug_level
169
     *
170
     * @return boolean
171
     */
172
    public function authorise($host, $port = false, $timeout = false, $username = '', $password = '', $debug_level = 0)
173
    {
174
        $this->host = $host;
175
        // If no port value provided, use default
176
        if (false === $port) {
177
            $this->port = static::DEFAULT_PORT;
178
        } else {
179
            $this->port = (integer)$port;
180
        }
181
        // If no timeout value provided, use default
182
        if (false === $timeout) {
183
            $this->tval = static::DEFAULT_TIMEOUT;
184
        } else {
185
            $this->tval = (integer)$timeout;
186
        }
187
        $this->do_debug = $debug_level;
188
        $this->username = $username;
189
        $this->password = $password;
190
        //  Reset the error log
191
        $this->errors = [];
192
        //  connect
193
        $result = $this->connect($this->host, $this->port, $this->tval);
194
        if ($result) {
195
            $login_result = $this->login($this->username, $this->password);
196
            if ($login_result) {
197
                $this->disconnect();
198
                return true;
199
            }
200
        }
201
        // We need to disconnect regardless of whether the login succeeded
202
        $this->disconnect();
203
        return false;
204
    }
205
206
    /**
207
     * Connect to a POP3 server.
208
     *
209
     * @param string $host
210
     * @param integer|boolean $port
211
     * @param integer $tval
212
     *
213
     * @return boolean
214
     */
215
    public function connect($host, $port = false, $tval = 30)
216
    {
217
        //  Are we already connected?
218
        if ($this->connected) {
219
            return true;
220
        }
221
222
        //On Windows this will raise a PHP Warning error if the hostname doesn't exist.
223
        //Rather than suppress it with @fsockopen, capture it cleanly instead
224
        set_error_handler([$this, 'catchWarning']);
225
226
        if (false === $port) {
227
            $port = static::DEFAULT_PORT;
228
        }
229
230
        //  connect to the POP3 server
231
        $this->pop_conn = fsockopen(
232
            $host, //  POP3 Host
233
            $port, //  Port #
234
            $errno, //  Error Number
235
            $errstr, //  Error Message
236
            $tval
237
        ); //  Timeout (seconds)
238
        //  Restore the error handler
239
        restore_error_handler();
240
241
        //  Did we connect?
242
        if (false === $this->pop_conn) {
243
            //  It would appear not...
244
            $this->setError(
245
                [
0 ignored issues
show
array('error' => "Failed...o, 'errstr' => $errstr) is of type array<string,integer|nul...errstr":"string|null"}>, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
246
                'error' => "Failed to connect to server $host on port $port",
247
                'errno' => $errno,
248
                'errstr' => $errstr
249
                ]
250
            );
251
            return false;
252
        }
253
254
        //  Increase the stream time-out
255
        stream_set_timeout($this->pop_conn, $tval, 0);
256
257
        //  Get the POP3 server response
258
        $pop3_response = $this->getResponse();
259
        //  Check for the +OK
260
        if ($this->checkResponse($pop3_response)) {
261
            //  The connection is established and the POP3 server is talking
262
            $this->connected = true;
263
            return true;
264
        }
265
        return false;
266
    }
267
268
    /**
269
     * Log in to the POP3 server.
270
     * Does not support APOP (RFC 2828, 4949).
271
     *
272
     * @param string $username
273
     * @param string $password
274
     *
275
     * @return boolean
276
     */
277
    public function login($username = '', $password = '')
278
    {
279
        if (!$this->connected) {
280
            $this->setError('Not connected to POP3 server');
281
        }
282
        if (empty($username)) {
283
            $username = $this->username;
284
        }
285
        if (empty($password)) {
286
            $password = $this->password;
287
        }
288
289
        // Send the Username
290
        $this->sendString("USER $username" . static::LE);
291
        $pop3_response = $this->getResponse();
292
        if ($this->checkResponse($pop3_response)) {
293
            // Send the Password
294
            $this->sendString("PASS $password" . static::LE);
295
            $pop3_response = $this->getResponse();
296
            if ($this->checkResponse($pop3_response)) {
297
                return true;
298
            }
299
        }
300
        return false;
301
    }
302
303
    /**
304
     * Disconnect from the POP3 server.
305
     */
306
    public function disconnect()
307
    {
308
        $this->sendString('QUIT');
309
        //The QUIT command may cause the daemon to exit, which will kill our connection
310
        //So ignore errors here
311
        try {
312
            @fclose($this->pop_conn);
313
        } catch (Exception $e) {
314
            //Do nothing
315
        };
316
    }
317
318
    /**
319
     * Get a response from the POP3 server.
320
     * $size is the maximum number of bytes to retrieve
321
     *
322
     * @param integer $size
323
     *
324
     * @return string
325
     */
326
    protected function getResponse($size = 128)
327
    {
328
        $response = fgets($this->pop_conn, $size);
329
        if ($this->do_debug >= 1) {
330
            echo 'Server -> Client: ', $response;
331
        }
332
        return $response;
333
    }
334
335
    /**
336
     * Send raw data to the POP3 server.
337
     *
338
     * @param string $string
339
     *
340
     * @return integer
341
     */
342
    protected function sendString($string)
343
    {
344
        if ($this->pop_conn) {
345
            if ($this->do_debug >= 2) { //Show client messages when debug >= 2
346
                echo 'Client -> Server: ', $string;
347
            }
348
            return fwrite($this->pop_conn, $string, strlen($string));
349
        }
350
        return 0;
351
    }
352
353
    /**
354
     * Checks the POP3 server response.
355
     * Looks for for +OK or -ERR.
356
     *
357
     * @param string $string
358
     *
359
     * @return boolean
360
     */
361
    protected function checkResponse($string)
362
    {
363
        if (substr($string, 0, 3) !== '+OK') {
364
            $this->setError(
365
                [
0 ignored issues
show
array('error' => "Server...' => 0, 'errstr' => '') is of type array<string,integer|str...er","errstr":"string"}>, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
366
                'error' => "Server reported an error: $string",
367
                'errno' => 0,
368
                'errstr' => ''
369
                ]
370
            );
371
            return false;
372
        } else {
373
            return true;
374
        }
375
    }
376
377
    /**
378
     * Add an error to the internal error store.
379
     * Also display debug output if it's enabled.
380
     *
381
     * @param string $error
382
     */
383
    protected function setError($error)
384
    {
385
        $this->errors[] = $error;
386
        if ($this->do_debug >= 1) {
387
            echo '<pre>';
388
            foreach ($this->errors as $error) {
389
                print_r($error);
390
            }
391
            echo '</pre>';
392
        }
393
    }
394
395
    /**
396
     * Get an array of error messages, if any.
397
     *
398
     * @return array
399
     */
400
    public function getErrors()
401
    {
402
        return $this->errors;
403
    }
404
405
    /**
406
     * POP3 connection error handler.
407
     *
408
     * @param integer $errno
409
     * @param string $errstr
410
     * @param string $errfile
411
     * @param integer $errline
412
     */
413
    protected function catchWarning($errno, $errstr, $errfile, $errline)
414
    {
415
        $this->setError(
416
            [
0 ignored issues
show
array('error' => 'Connec... 'errline' => $errline) is of type array<string,string|inte...","errline":"integer"}>, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
417
            'error' => 'Connecting to the POP3 server raised a PHP warning: ',
418
            'errno' => $errno,
419
            'errstr' => $errstr,
420
            'errfile' => $errfile,
421
            'errline' => $errline
422
            ]
423
        );
424
    }
425
}
426