Passed
Pull Request — master (#42)
by
unknown
02:59
created

Composer::setEventManager()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

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