Composer::compose()   C
last analyzed

Complexity

Conditions 7
Paths 32

Size

Total Lines 77
Code Lines 47

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 44
CRAP Score 7.0127

Importance

Changes 0
Metric Value
dl 0
loc 77
ccs 44
cts 47
cp 0.9362
rs 6.5755
c 0
b 0
f 0
cc 7
eloc 47
nc 32
nop 3
crap 7.0127

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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\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
        }
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
        }
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
        }
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
        }
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