Completed
Push — master ( 22dadb...55e860 )
by Roberto
06:45 queued 03:03
created

Mail::renderTemplate()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 34
Code Lines 30

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 34
c 0
b 0
f 0
ccs 0
cts 34
cp 0
rs 8.8571
cc 1
eloc 30
nc 1
nop 8
crap 2

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
3
namespace NFePHP\Mail;
4
5
/**
6
 * Class for sending emails related to SPED services
7
 *
8
 * @category  NFePHP
9
 * @package   NFePHP\Mail\Mail
10
 * @copyright NFePHP Copyright (c) 2016
11
 * @license   http://www.gnu.org/licenses/lgpl.txt LGPLv3+
12
 * @license   https://opensource.org/licenses/MIT MIT
13
 * @license   http://www.gnu.org/licenses/gpl.txt GPLv3+
14
 * @author    Roberto L. Machado <linux.rlm at gmail dot com>
15
 * @link      http://github.com/nfephp-org/sped-mail for the canonical source repository
16
 */
17
18
use stdClass;
19
use DOMDocument;
20
use DateTime;
21
use InvalidArgumentException;
22
use RuntimeException;
23
use NFePHP\Mail\Base;
24
use PHPMailer;
25
use Html2Text\Html2Text;
26
27
class Mail extends Base
28
{
29
    /**
30
     * config
31
     * @var stdClass
32
     */
33
    protected $config;
34
35
    /**
36
     * Html Body mail message
37
     * @var string
38
     */
39
    protected $body;
40
    /**
41
     * Subject for email
42
     * @var string
43
     */
44
    protected $subject;
45
46
    /**
47
     * Xml content
48
     * @var string
49
     */
50
    protected $xml;
51
    /**
52
     * PDF content
53
     * @var string
54
     */
55
    protected $pdf;
56
    
57
    /**
58
     * Constructor
59
     * @param \stdClass $config
60
     */
61
    public function __construct(stdClass $config, PHPMailer $mailer = null)
62
    {
63
        $this->mail = $mailer;
64
        if (is_null($mailer)) {
65
            $this->mail = new PHPMailer();
66
        }
67
        $this->config = $config;
68
        $this->loadService($config);
69
        $this->fields = new stdClass();
0 ignored issues
show
Documentation Bug introduced by
It seems like new \stdClass() of type object<stdClass> is incompatible with the declared type object<NFePHP\Mail\stdClass> of property $fields.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
70
        $this->fields->destinatario = '';
71
        $this->fields->data = '';
72
        $this->fields->numero = '';
73
        $this->fields->valor = 0;
74
        $this->fields->chave = '';
75
        $this->fields->data = '';
76
        $this->fields->correcao = '';
77
        $this->fields->conduso = '';
78
    }
79
    
80
    /**
81
     * Load parameters to PHPMailer class
82
     * @param stdClass $config
83
     */
84
    protected function loadService(stdClass $config)
85
    {
86
        $this->mail->CharSet = 'UTF-8';
87
        $this->mail->isSMTP();
88
        $this->mail->Host = $config->host;
89
        $this->mail->SMTPAuth = true;
90
        $this->mail->Username = $config->user;
91
        $this->mail->Password = $config->password;
92
        $this->mail->SMTPSecure = $config->secure;
93
        $this->mail->Port = $config->port;
94
        $this->mail->setFrom($config->from, $config->fantasy);
95
        $this->mail->addReplyTo($config->replyTo, $config->replyName);
96
    }
97
    
98
    /**
99
     * Sets a template for body mail
100
     * If no template is passed, it will be used a standard template
101
     * see Base::class
102
     * @param string $htmlTemplate
103
     */
104
    public function setTemplate($htmlTemplate)
105
    {
106
        if ($htmlTemplate != '') {
107
            $this->template = $htmlTemplate;
108
        }
109
    }
110
    
111
    /**
112
     * Load the documents to send
113
     * XML document is required, but PDF is not
114
     * @param string $xml content or path NFe, CTe or CCe in XML
115
     * @param string $pdf content or path document from NFe, CTe or CCe
116
     */
117
    public function loadDocuments($xml, $pdf = '')
118
    {
119
        $this->xml = $xml;
120
        $this->pdf = $pdf;
121
        if (is_file($xml)) {
122
            $this->xml = file_get_contents($xml);
123
        }
124
        if (is_file($pdf)) {
125
            $this->pdf = file_get_contents($pdf);
126
        }
127
        //get xml data
128
        $this->getXmlData($this->xml);
129
    }
130
    
131
    /**
132
     * Search xml for data
133
     * @param string $xml
134
     * @throws InvalidArgumentException
135
     */
136
    protected function getXmlData($xml)
137
    {
138
        $dom = new DOMDocument('1.0', 'UTF-8');
139
        $dom->preserveWhiteSpace = false;
140
        $dom->loadXML($xml);
141
        $root = $dom->documentElement;
142
        $name = $root->tagName;
143
        switch ($name) {
144
            case 'nfeProc':
145
            case 'NFe':
146
                $type = 'NFe';
147
                $this->fields->destinatario = $dom->getElementsByTagName('dest')->item(0)
148
                    ->getElementsByTagName('xNome')->item(0)->nodeValue;
149
                $this->fields->data = $dom->getElementsByTagName('ide')->item(0)
150
                    ->getElementsByTagName('dhEmi')->item(0)->nodeValue;
151
                $this->fields->numero = $dom->getElementsByTagName('ide')->item(0)
152
                     ->getElementsByTagName('nNF')->item(0)->nodeValue;
153
                $this->fields->valor = $dom->getElementsByTagName('vNF')->item(0)->nodeValue;
154
                $this->subject = "NFe n. ".$this->fields->numero." - ".$this->config->fantasy;
155
                break;
156
            case 'cteProc':
157
            case 'CTe':
158
                $type = 'CTe';
159
                $this->fields->destinatario = $dom->getElementsByTagName('dest')->item(0)
160
                    ->getElementsByTagName('xNome')->item(0)->nodeValue;
161
                $this->fields->data = $dom->getElementsByTagName('ide')->item(0)
162
                    ->getElementsByTagName('dhEmi')->item(0)->nodeValue;
163
                $this->fields->numero = $dom->getElementsByTagName('ide')->item(0)
164
                    ->getElementsByTagName('nCT')->item(0)->nodeValue;
165
                $this->fields->valor = $dom->getElementsByTagName('vRec')->item(0)->nodeValue;
166
                $this->subject = "CTe n. ".$this->fields->numero." - ".$this->config->fantasy;
167
                break;
168
            case 'procEventoNFe':
169
            case 'procEventoCTe':
170
                $type = 'CCe';
171
                $this->fields->chave = $dom->getElementsByTagName('chNFe')->item(0)->nodeValue;
172
                $this->fields->data = $dom->getElementsByTagName('dhEvento')->item(0)->nodeValue;
173
                $this->fields->correcao = $dom->getElementsByTagName('xCorrecao')->item(0)->nodeValue;
174
                $this->fields->conduso = $dom->getElementsByTagName('xCondUso')->item(0)->nodeValue;
175
                if (empty($this->fields->chave)) {
176
                    $this->fields->chave = $dom->getElementsByTagName('chCTe')->item(0)->nodeValue;
177
                }
178
                $this->subject = "Carta de Correção ". $this->config->fantasy;
179
                break;
180
            default:
181
                $type = '';
182
        }
183
        //get email adresses from xml, if exists
184
        //may have one address in <dest><email>
185
        $email = !empty($dom->getElementsByTagName('email')->item(0)->nodeValue) ?
186
            $dom->getElementsByTagName('email')->item(0)->nodeValue : '';
187
        if (! empty($email)) {
188
            $this->addresses[] = $email;
189
        }
190
        //may have others in <obsCont xCampo="email"><xTexto>[email protected]</xTexto>
191
        $obs = $dom->getElementsByTagName('obsCont');
192
        foreach ($obs as $ob) {
193
            if (strtoupper($ob->getAttribute('xCampo')) === 'EMAIL') {
194
                $this->addresses[] = $ob->getElementsByTagName('xTexto')->item(0)->nodeValue;
195
            }
196
        }
197
        //xml may be a NFe or a CTe or a CCe nothing else
198
        if ($type != 'NFe' && $type != 'CTe' && $type != 'CCe') {
199
            $msg = "Você deve passar apenas uma NFe ou um CTe ou um CCe. "
200
                    . "Esse documento não foi reconhecido.";
201
            throw new InvalidArgumentException($msg);
202
        }
203
        $this->type = $type;
204
    }
205
    
206
    /**
207
     * Render a template with valid data
208
     * @param string $template
209
     * @param string $destinatario
210
     * @param string $data
211
     * @param string $numero
212
     * @param string $valor
213
     * @param string $chave
214
     * @param string $correcao
215
     * @param string $conduso
216
     * @return string
217
     */
218
    protected function renderTemplate(
219
        $template,
220
        $destinatario = '',
221
        $data = '',
222
        $numero = '',
223
        $valor = 0,
224
        $chave = '',
225
        $correcao = '',
226
        $conduso = ''
227
    ) {
228
        $dt = new \DateTime(str_replace('T', ' ', $data));
229
        $search = array(
230
            '{destinatario}',
231
            '{data}',
232
            '{numero}',
233
            '{valor}',
234
            '{emitente}',
235
            '{chave}',
236
            '{correcao}',
237
            '{conduso}'
238
        );
239
        $replace = array(
240
          $destinatario,
241
          $dt->format('d/m/Y'),
242
          $numero,
243
          number_format($valor, 2, ',', '.'),
244
          $this->config->fantasy,
245
          $chave,
246
          $correcao,
247
          $conduso
248
        );
249
        $template = str_replace($search, $replace, $template);
250
        return $template;
251
    }
252
    
253
    /**
254
     * Set all addresses including those that exists in the xml document
255
     * Send email only to listed addresses ignoring all email addresses in xml
256
     * @param array $addresses
257
     */
258
    protected function setAddresses(array $addresses = [])
259
    {
260
        if (!empty($addresses)) {
261
            $this->addresses = $addresses;
262
        }
263
        $this->removeInvalidAdresses();
264
    }
265
    
266
    /**
267
     * Send mail
268
     * If no parameter was passed, only the email address contained in
269
     * the xml will be used
270
     * @param array $addresses
271
     * @return boolean
272
     * @throws RuntimeException
273
     */
274
    public function send(array $addresses = [])
275
    {
276
        $this->setAddresses($addresses);
277
        if (empty($this->addresses)) {
278
            $msg = 'Não foram passados endereços de email validos !!';
279
            throw new RuntimeException($msg);
280
        }
281
        foreach ($this->addresses as $address) {
282
            $this->mail->addAddress($address);
283
        }
284
        $body = $this->render();
285
        $this->mail->isHTML(true);
286
        $this->mail->Subject = $this->subject;
287
        $this->mail->Body = $body;
288
        $this->mail->AltBody = Html2Text::convert($body);
289
        $this->attach();
290
        if (!$this->mail->send()) {
291
            $msg = 'A mensagem não pode ser enviada. Mail Error: ' . $this->mail->ErrorInfo;
292
            throw new RuntimeException($msg);
293
        }
294
        $this->mail->ClearAllRecipients();
295
        $this->mail->ClearAttachments();
296
        return true;
297
    }
298
    
299
    
300
    /**
301
     * Configure and send documents
302
     * @param stdClass $config
303
     * @param type $xml
304
     * @param type $pdf
305
     * @param array $addresses
306
     * @param type $htmltemplate
307
     * @param PHPMailer $mailer
308
     * @return \static
309
     */
310
    public static function sendMail(
311
        stdClass $config,
312
        $xml,
313
        $pdf = '',
314
        array $addresses = [],
315
        $htmltemplate = '',
316
        PHPMailer $mailer = null
317
    ) {
318
        $mail = new static($config, $mailer);
319
        $mail->loadDocuments($xml, $pdf);
320
        $mail->setTemplate($htmltemplate);
321
        $mail->send($addresses);
322
        return $mail;
323
    }
324
}
325