Passed
Push — master ( 295c7f...61bbf4 )
by Zaahid
09:01
created

MailMimeParser::parse()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 2.0078

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 6
c 1
b 0
f 0
dl 0
loc 10
ccs 7
cts 8
cp 0.875
rs 10
cc 2
nc 2
nop 2
crap 2.0078
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
use ZBateson\MailMimeParser\Parser\MessageParser;
10
use GuzzleHttp\Psr7\CachingStream;
11
use GuzzleHttp\Psr7\Utils;
12
use Psr\Http\Message\StreamInterface;
13
14
/**
15
 * Parses a MIME message into an {@see IMessage} object.
16
 *
17
 * The class sets up the Pimple dependency injection container with the ability
18
 * to override and/or provide specialized provider
19
 * {@see https://pimple.symfony.com/ \Pimple\ServiceProviderInterface}
20
 * classes to extend default classes used by MailMimeParser.
21
 *
22
 * To invoke, call parse on a MailMimeParser object.
23
 *
24
 * ```php
25
 * $parser = new MailMimeParser();
26
 * // the resource is attached due to the second parameter being true and will
27
 * // be closed when the returned IMessage is destroyed
28
 * $message = $parser->parse(fopen('path/to/file.txt'), true);
29
 * // use $message here
30
 * ```
31
 *
32
 * @author Zaahid Bateson
33
 */
34
class MailMimeParser
35
{
36
    /**
37
     * @var string the default charset used to encode strings (or string content
38
     *      like streams) returned by MailMimeParser (for e.g. the string
39
     *      returned by calling $message->getTextContent()).
40
     */
41
    const DEFAULT_CHARSET = 'UTF-8';
42
43
    /**
44
     * @var Container dependency injection container
45
     */
46
    protected static $di = null;
47
48
    /**
49
     * @var MessageParser for parsing messages
50
     */
51
    protected $messageParser;
52
53
    /**
54
     * Returns the container.
55
     *
56
     * @return Container
57
     */
58 105
    public static function getDependencyContainer()
59
    {
60 105
        return static::$di;
61
    }
62
63
    /**
64
     * (Re)creates the container using the passed providers.
65
     *
66
     * This is necessary if configuration needs to be reset to parse emails
67
     * differently.
68
     *
69
     * Note that reconfiguring the dependency container can have an affect on
70
     * existing objects -- for instance if a provider were to override a
71
     * factory class, and an operation on an existing instance were to try to
72
     * create an object using that factory class, the new factory class would be
73
     * returned.  In other words, references to the Container are not maintained
74
     * in a non-static context separately, so care should be taken when
75
     * reconfiguring the parser.
76
     *
77
     * @param \Pimple\ServiceProviderInterface[] $providers
78
     */
79 1
    public static function configureDependencyContainer(array $providers = [])
80
    {
81 1
        static::$di = new Container();
82 1
        $di = static::$di;
83 1
        foreach ($providers as $provider) {
84
            $di->register($provider);
85
        }
86
    }
87
88
    /**
89
     * Override the dependency container completely.  If multiple configurations
90
     * are known to be needed, it would be better to keep the different
91
     * Container configurations and call setDependencyContainer instead of
92
     * {@see MailMimeParser::configureDependencyContainer}, which instantiates a
93
     * new {@see Container} on every call.
94
     *
95
     * @param Container $di
96
     */
97 4
    public static function setDependencyContainer(Container $di = null)
98
    {
99 4
        static::$di = $di;
100
    }
101
    
102
    /**
103
     * Initializes the dependency container if not already initialized.
104
     *
105
     * To configure custom {@see https://pimple.symfony.com/ \Pimple\ServiceProviderInterface}
106
     * objects, call {@see MailMimeParser::configureDependencyContainer()}
107
     * before creating a MailMimeParser instance.
108
     */
109 108
    public function __construct()
110
    {
111 108
        if (static::$di === null) {
112 1
            static::configureDependencyContainer();
113
        }
114 108
        $di = static::$di;
115 108
        $this->messageParser = $di['ZBateson\MailMimeParser\Parser\MessageParser'];
116
    }
117
118
    /**
119
     * Parses the passed stream handle or string into an {@see IMessage} object
120
     * and returns it.
121
     *
122
     * If the passed $resource is a resource handle or StreamInterface, the
123
     * resource must remain open while the returned IMessage object exists.
124
     * Pass true as the second argument to have the resource attached to the
125
     * IMessage and closed for you when it's destroyed, or pass false to
126
     * manually close it if it should remain open after the IMessage object is
127
     * destroyed.
128
     *
129
     * @param resource|StreamInterface|string $resource The resource handle to
130
     *        the input stream of the mime message, or a string containing a
131
     *        mime message.
132
     * @param bool $attached pass true to have it attached to the returned
133
     *        IMessage and destroyed with it.
134
     * @return \ZBateson\MailMimeParser\IMessage
135
     */
136 107
    public function parse($resource, $attached)
137
    {
138 107
        $stream = Utils::streamFor(
139 107
            $resource,
140 107
            [ 'metadata' => [ 'mmp-detached-stream' => ($attached !== true) ] ]
141 107
        );
142 107
        if (!$stream->isSeekable()) {
143
            $stream = new CachingStream($stream);
144
        }
145 107
        return $this->messageParser->parse($stream);
146
    }
147
}
148