Passed
Push — v3_compat ( 23df76...881577 )
by Mateusz
04:16
created

Composer   A

Complexity

Total Complexity 14

Size/Duplication

Total Lines 170
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 13

Test Coverage

Coverage 93.06%

Importance

Changes 11
Bugs 1 Features 0
Metric Value
wmc 14
c 11
b 1
f 0
lcom 1
cbo 13
dl 0
loc 170
ccs 67
cts 72
cp 0.9306
rs 10

7 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A setEventManager() 0 6 1
A getEventManager() 0 8 2
A setRenderer() 0 6 1
A getRenderer() 0 4 1
A getEvent() 0 7 1
C compose() 0 77 7
1
<?php
2
/**
3
 * MtMail - e-mail module for Zend Framework 2
4
 *
5
 * @link      http://github.com/mtymek/MtMail
6
 * @copyright Copyright (c) 2013-2014 Mateusz Tymek
7
 * @license   BSD 2-Clause
8
 */
9
10
namespace MtMail\Service;
11
12
use MtMail\Event\ComposerEvent;
13
use MtMail\Exception\InvalidArgumentException;
14
use MtMail\Renderer\RendererInterface;
15
use MtMail\Template\HtmlTemplateInterface;
16
use MtMail\Template\TemplateInterface;
17
use MtMail\Template\TextTemplateInterface;
18
use Zend\EventManager\EventManager;
19
use Zend\EventManager\EventManagerAwareInterface;
20
use Zend\EventManager\EventManagerInterface;
21
use Zend\Mail\Message;
22
use Zend\View\Model\ModelInterface;
23
use Zend\Mime\Message as MimeMessage;
24
use Zend\Mime\Part as MimePart;
25
use Zend\View\Model\ViewModel;
26
27
class Composer implements EventManagerAwareInterface
28
{
29
    /**
30
     * @var RendererInterface
31
     */
32
    protected $renderer;
33
34
    /**
35
     * @var EventManagerInterface
36
     */
37
    protected $eventManager;
38
39
    /**
40
     * Class constructor
41
     *
42
     * @param RendererInterface $renderer
43
     */
44 10
    public function __construct(RendererInterface $renderer)
45
    {
46 10
        $this->renderer = $renderer;
47 10
    }
48
49
    /**
50
     * Inject an EventManager instance
51
     *
52
     * @param  EventManagerInterface $eventManager
53
     * @return self
54
     */
55 3
    public function setEventManager(EventManagerInterface $eventManager)
56
    {
57 3
        $this->eventManager = $eventManager;
58
59 3
        return $this;
60
    }
61
62
    /**
63
     * Retrieve the event manager
64
     *
65
     * Lazy-loads an EventManager instance if none registered.
66
     *
67
     * @return EventManagerInterface
68
     */
69 8
    public function getEventManager()
70
    {
71 8
        if (null === $this->eventManager) {
72 6
            $this->eventManager = new EventManager();
73 6
        }
74
75 8
        return $this->eventManager;
76
    }
77
78
    /**
79
     * @param  \MtMail\Renderer\RendererInterface $renderer
80
     * @return self
81
     */
82 1
    public function setRenderer($renderer)
83
    {
84 1
        $this->renderer = $renderer;
85
86 1
        return $this;
87
    }
88
89
    /**
90
     * @return \MtMail\Renderer\RendererInterface
91
     */
92 3
    public function getRenderer()
93
    {
94 3
        return $this->renderer;
95
    }
96
97
    /**
98
     * Create and return event used by compose and send methods
99
     *
100
     * @return ComposerEvent
101
     */
102 5
    protected function getEvent()
103
    {
104 5
        $event = new ComposerEvent();
105 5
        $event->setTarget($this);
106
107 5
        return $event;
108
    }
109
110
    /**
111
     * Build e-mail message
112
     *
113
     * @param  TemplateInterface        $template
114
     * @param  array                    $headers
115
     * @param  ModelInterface           $viewModel
116
     * @throws InvalidArgumentException if template is not string nor TemplateInterface
117
     * @return Message
118
     */
119 5
    public function compose(array $headers, TemplateInterface $template, ModelInterface $viewModel = null)
120
    {
121 5
        if (null == $viewModel) {
122
            $viewModel = new ViewModel();
123
        }
124
125 5
        $event = $this->getEvent();
126 5
        $event->setTemplate($template);
127 5
        $em = $this->getEventManager();
128
129
        // 1. Trigger pre event
130 5
        $event->setName(ComposerEvent::EVENT_COMPOSE_PRE);
131 5
        $em->triggerEvent($event);
132
133
        // 2. inject headers
134 5
        $event->setName(ComposerEvent::EVENT_HEADERS_PRE);
135 5
        $em->triggerEvent($event);
136 5
        foreach ($headers as $name => $value) {
137 1
            $event->getMessage()->getHeaders()->addHeaderLine($name, $value);
138 5
        }
139 5
        $event->setName(ComposerEvent::EVENT_HEADERS_POST);
140 5
        $em->triggerEvent($event);
141
142
        // prepare placeholder for message body
143 5
        $body = new MimeMessage();
144
145
        // 3. Render plain text template
146 5
        if ($template instanceof TextTemplateInterface) {
147 2
            $textViewModel = clone $viewModel;
148 2
            $textViewModel->setTemplate($template->getTextTemplateName());
149 2
            $event->setViewModel($textViewModel);
150
151 2
            $event->setName(ComposerEvent::EVENT_TEXT_BODY_PRE);
152 2
            $em->triggerEvent($event);
153
154 2
            $text = new MimePart($this->renderer->render($event->getViewModel()));
155 2
            $text->type = 'text/plain';
156 2
            $text->charset = $event->getMessage()->getHeaders()->getEncoding();
157 2
            $body->addPart($text);
158
159 2
            $event->setName(ComposerEvent::EVENT_TEXT_BODY_POST);
160 2
            $em->triggerEvent($event);
161 2
        }
162
163
        // 4. Render HTML template
164 5
        if ($template instanceof HtmlTemplateInterface) {
165 3
            $htmlViewModel = clone $viewModel;
166 3
            $htmlViewModel->setTemplate($template->getHtmlTemplateName());
167 3
            $event->setViewModel($htmlViewModel);
168
169 3
            $event->setName(ComposerEvent::EVENT_HTML_BODY_PRE);
170 3
            $em->triggerEvent($event);
171
172 3
            $html = new MimePart($this->renderer->render($event->getViewModel()));
173 3
            $html->type = 'text/html';
174 3
            $html->charset = $event->getMessage()->getHeaders()->getEncoding();
175 3
            $body->addPart($html);
176
177 3
            $event->setName(ComposerEvent::EVENT_HTML_BODY_POST);
178 3
            $em->triggerEvent($event);
179 3
        }
180
181
        // 5. inject body into message
182 5
        $event->setBody($body);
183 5
        $event->getMessage()->setBody($body);
184
185
        // 6. set multipart/alternative when both versions are available
186 5
        if ($template instanceof TextTemplateInterface && $template instanceof HtmlTemplateInterface) {
187
            $event->getMessage()->getHeaders()->get('content-type')->setType('multipart/alternative')
188
                ->addParameter('boundary', $body->getMime()->boundary());
189
        }
190
191 5
        $event->setName(ComposerEvent::EVENT_COMPOSE_POST);
192 5
        $em->triggerEvent($event);
193
194 5
        return $event->getMessage();
195
    }
196
}
197