Completed
Push — master ( 42b3e6...c7cf7f )
by Zaahid
02:29
created

MailMimeParser::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 4
rs 10
cc 1
eloc 2
nc 1
nop 0
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
    public function __construct()
32
    {
33
        $this->di = SimpleDi::singleton();
34
    }
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 if set to true, treats the message as a raw message
48
     *        from SMTP, ending input on the first ".\r\n" it finds and
49
     *        replacing ".." at the beginning of a line with a single ".".
50
     * @return \ZBateson\MailMimeParser\Message
51
     */
52
    public function parse($handle, $isSmtp = false)
53
    {
54
        // $tempHandle is attached to $message, and closed in its destructor
55
        $tempHandle = fopen('php://temp', 'rw');
56
        $this->copyToTmpFile($tempHandle, $handle, $isSmtp);
57
        $parser = $this->di->newMessageParser();
58
        $message = $parser->parse($tempHandle);
59
        return $message;
60
    }
61
62
    /**
63
     * Replaces lines starting with '..' with a single dot.  Returns false if a
64
     * line containing a single '.' character is found signifying the last line
65
     * of the input stream.
66
     * 
67
     * @param string $line
68
     * @return boolean
69
     */
70
    private function filterSmtpLines(&$line)
71
    {
72
        if (rtrim($line, "\r\n") === '.') {
73
            return false;
74
        } elseif (strpos($line, '..') === 0) {
75
            $line = substr($line, 1);
76
        }
77
        return true;
78
    }
79
    
80
    /**
81
     * Copies the input stream $inHandle into the $tmpHandle resource.
82
     * Optionally treats the input as an SMTP input message with $isSmtp,
83
     * considering end of input to be the first ".\r\n" it encounters.
84
     * 
85
     * @param resource $tmpHandle the temporary resource handle
86
     * @param resource $inHandle the input stream resource handle
87
     * @param bool $isSmtp set to true if $inHandle is an SMTP input stream
88
     */
89
    protected function copyToTmpFile($tmpHandle, $inHandle, $isSmtp)
90
    {
91
        do {
92
            $line = fgets($inHandle);
93
            if ($isSmtp && !$this->filterSmtpLines($line)) {
94
                break;
95
            }
96
            fwrite($tmpHandle, $line);
97
        } while (!feof($inHandle));
98
        rewind($tmpHandle);
99
    }
100
}
101