1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* This file is part of the ZBateson\MailMimeParser project. |
4
|
|
|
* |
5
|
|
|
* @license http://opensource.org/licenses/bsd-license.php BSD |
6
|
|
|
*/ |
7
|
|
|
namespace ZBateson\MailMimeParser; |
8
|
|
|
|
9
|
|
|
/** |
10
|
|
|
* Parses a MIME message into a \ZBateson\MailMimeParser\Message object. |
11
|
|
|
* |
12
|
|
|
* To invoke, call parse on a MailMimeParser object. |
13
|
|
|
* |
14
|
|
|
* $handle = fopen('path/to/file.txt'); |
15
|
|
|
* $parser = new MailMimeParser(); |
16
|
|
|
* $parser->parse($handle); |
17
|
|
|
* fclose($handle); |
18
|
|
|
* |
19
|
|
|
* @author Zaahid Bateson |
20
|
|
|
*/ |
21
|
|
|
class MailMimeParser |
22
|
|
|
{ |
23
|
|
|
/** |
24
|
|
|
* @var \ZBateson\MailMimeParser\SimpleDi dependency injection container |
25
|
|
|
*/ |
26
|
|
|
protected $di; |
27
|
|
|
|
28
|
|
|
/** |
29
|
|
|
* Sets up the parser. |
30
|
|
|
*/ |
31
|
3 |
|
public function __construct() |
32
|
|
|
{ |
33
|
3 |
|
$this->di = SimpleDi::singleton(); |
34
|
3 |
|
} |
35
|
|
|
|
36
|
|
|
/** |
37
|
|
|
* Parses the passed stream handle into a ZBateson\MailMimeParser\Message |
38
|
|
|
* object and returns it. |
39
|
|
|
* |
40
|
|
|
* Internally, the message is first copied to a temp stream (with php://temp |
41
|
|
|
* which may keep it in memory or write it to disk) and its stream is used. |
42
|
|
|
* That way if the message is too large to hold in memory it can be written |
43
|
|
|
* to a temporary file if need be. |
44
|
|
|
* |
45
|
|
|
* @param resource $handle the resource handle to the input stream of the |
46
|
|
|
* mime message |
47
|
|
|
* @param bool $isSmtp Deprecated and will be removed in 0.3.0 -- if set to |
48
|
|
|
* true, treats the message as a raw message from SMTP, ending input |
49
|
|
|
* on the first ".\r\n" it finds and replacing ".." at the beginning |
50
|
|
|
* of a line with a single ".". |
51
|
|
|
* @return \ZBateson\MailMimeParser\Message |
52
|
|
|
*/ |
53
|
2 |
|
public function parse($handle, $isSmtp = false) |
54
|
|
|
{ |
55
|
|
|
// $tempHandle is attached to $message, and closed in its destructor |
56
|
2 |
|
$tempHandle = fopen('php://temp', 'w+'); |
57
|
2 |
|
if ($isSmtp) { |
58
|
1 |
|
$this->copyToTmpFile($tempHandle, $handle); |
|
|
|
|
59
|
1 |
|
} else { |
60
|
1 |
|
stream_copy_to_stream($handle, $tempHandle); |
61
|
1 |
|
rewind($tempHandle); |
62
|
|
|
} |
63
|
2 |
|
$parser = $this->di->newMessageParser(); |
64
|
2 |
|
$message = $parser->parse($tempHandle); |
65
|
2 |
|
return $message; |
66
|
|
|
} |
67
|
|
|
|
68
|
|
|
/** |
69
|
|
|
* Replaces lines starting with '..' with a single dot. Returns false if a |
70
|
|
|
* line containing a single '.' character is found signifying the last line |
71
|
|
|
* of the input stream. |
72
|
|
|
* |
73
|
|
|
* @deprecated removed in 0.3.0 |
74
|
|
|
* @param string $line |
75
|
|
|
* @return boolean |
76
|
|
|
*/ |
77
|
|
|
private function filterSmtpLines(&$line) |
78
|
|
|
{ |
79
|
|
|
if (rtrim($line, "\r\n") === '.') { |
80
|
|
|
return false; |
81
|
|
|
} elseif (strpos($line, '..') === 0) { |
82
|
|
|
$line = substr($line, 1); |
83
|
|
|
} |
84
|
|
|
return true; |
85
|
|
|
} |
86
|
|
|
|
87
|
|
|
/** |
88
|
|
|
* Copies the input stream $inHandle into the $tmpHandle resource. |
89
|
|
|
* Optionally treats the input as an SMTP input message with $isSmtp, |
90
|
|
|
* considering end of input to be the first ".\r\n" it encounters. |
91
|
|
|
* |
92
|
|
|
* @deprecated removed in 0.3.0 |
93
|
|
|
* @param resource $tmpHandle the temporary resource handle |
94
|
|
|
* @param resource $inHandle the input stream resource handle |
95
|
|
|
*/ |
96
|
|
|
protected function copyToTmpFile($tmpHandle, $inHandle) |
97
|
|
|
{ |
98
|
|
|
do { |
99
|
|
|
$line = fgets($inHandle); |
100
|
|
|
if (!$this->filterSmtpLines($line)) { |
|
|
|
|
101
|
|
|
break; |
102
|
|
|
} |
103
|
|
|
fwrite($tmpHandle, $line); |
104
|
|
|
} while (!feof($inHandle)); |
105
|
|
|
rewind($tmpHandle); |
106
|
|
|
} |
107
|
|
|
} |
108
|
|
|
|
This method has been deprecated. The supplier of the class has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.