Completed
Push — master ( baa46f...086585 )
by Roberto
05:33 queued 02:06
created

Mail   A

Complexity

Total Complexity 30

Size/Duplication

Total Lines 240
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
wmc 30
lcom 1
cbo 3
dl 0
loc 240
ccs 0
cts 159
cp 0
rs 10
c 0
b 0
f 0

8 Methods

Rating   Name   Duplication   Size   Complexity  
A loadService() 0 13 1
A setTemplate() 0 6 2
A loadDocuments() 0 13 3
A __construct() 0 18 2
D getXmlData() 0 69 15
A setAddresses() 0 7 2
B send() 0 24 4
A sendMail() 0 14 1
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
     * Constructor
48
     * @param \stdClass $config
49
     */
50
    public function __construct(stdClass $config, PHPMailer $mailer = null)
51
    {
52
        $this->mail = $mailer;
53
        if (is_null($mailer)) {
54
            $this->mail = new PHPMailer();
55
        }
56
        $this->config = $config;
57
        $this->loadService($config);
58
        $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...
59
        $this->fields->destinatario = '';
60
        $this->fields->data = '';
61
        $this->fields->numero = '';
62
        $this->fields->valor = 0;
63
        $this->fields->chave = '';
64
        $this->fields->data = '';
65
        $this->fields->correcao = '';
66
        $this->fields->conduso = '';
67
    }
68
    
69
    /**
70
     * Load parameters to PHPMailer class
71
     * @param stdClass $config
72
     */
73
    protected function loadService(stdClass $config)
74
    {
75
        $this->mail->CharSet = 'UTF-8';
76
        $this->mail->isSMTP();
77
        $this->mail->Host = $config->host;
78
        $this->mail->SMTPAuth = true;
79
        $this->mail->Username = $config->user;
80
        $this->mail->Password = $config->password;
81
        $this->mail->SMTPSecure = $config->secure;
82
        $this->mail->Port = $config->port;
83
        $this->mail->setFrom($config->from, $config->fantasy);
84
        $this->mail->addReplyTo($config->replyTo, $config->replyName);
85
    }
86
    
87
    /**
88
     * Sets a template for body mail
89
     * If no template is passed, it will be used a standard template
90
     * see Base::class
91
     * @param string $htmlTemplate
92
     */
93
    public function setTemplate($htmlTemplate)
94
    {
95
        if ($htmlTemplate != '') {
96
            $this->template = $htmlTemplate;
97
        }
98
    }
99
    
100
    /**
101
     * Load the documents to send
102
     * XML document is required, but PDF is not
103
     * @param string $xml content or path NFe, CTe or CCe in XML
104
     * @param string $pdf content or path document from NFe, CTe or CCe
105
     */
106
    public function loadDocuments($xml, $pdf = '')
107
    {
108
        $this->xml = $xml;
109
        $this->pdf = $pdf;
110
        if (is_file($xml)) {
111
            $this->xml = file_get_contents($xml);
112
        }
113
        if (is_file($pdf)) {
114
            $this->pdf = file_get_contents($pdf);
115
        }
116
        //get xml data
117
        $this->getXmlData($this->xml);
118
    }
119
    
120
    /**
121
     * Search xml for data
122
     * @param string $xml
123
     * @throws InvalidArgumentException
124
     */
125
    protected function getXmlData($xml)
126
    {
127
        $dom = new DOMDocument('1.0', 'UTF-8');
128
        $dom->preserveWhiteSpace = false;
129
        $dom->loadXML($xml);
130
        $root = $dom->documentElement;
131
        $name = $root->tagName;
132
        switch ($name) {
133
            case 'nfeProc':
134
            case 'NFe':
135
                $type = 'NFe';
136
                $this->fields->destinatario = $dom->getElementsByTagName('dest')->item(0)
137
                    ->getElementsByTagName('xNome')->item(0)->nodeValue;
138
                $this->fields->data = $dom->getElementsByTagName('ide')->item(0)
139
                    ->getElementsByTagName('dhEmi')->item(0)->nodeValue;
140
                $this->fields->numero = $dom->getElementsByTagName('ide')->item(0)
141
                     ->getElementsByTagName('nNF')->item(0)->nodeValue;
142
                $this->fields->valor = $dom->getElementsByTagName('vNF')->item(0)->nodeValue;
143
                $this->subject = "NFe n. ".$this->fields->numero." - ".$this->config->fantasy;
144
                break;
145
            case 'cteProc':
146
            case 'CTe':
147
                $type = 'CTe';
148
                $this->fields->destinatario = $dom->getElementsByTagName('dest')->item(0)
149
                    ->getElementsByTagName('xNome')->item(0)->nodeValue;
150
                $this->fields->data = $dom->getElementsByTagName('ide')->item(0)
151
                    ->getElementsByTagName('dhEmi')->item(0)->nodeValue;
152
                $this->fields->numero = $dom->getElementsByTagName('ide')->item(0)
153
                    ->getElementsByTagName('nCT')->item(0)->nodeValue;
154
                $this->fields->valor = $dom->getElementsByTagName('vRec')->item(0)->nodeValue;
155
                $this->subject = "CTe n. ".$this->fields->numero." - ".$this->config->fantasy;
156
                break;
157
            case 'procEventoNFe':
158
            case 'procEventoCTe':
159
                $type = 'CCe';
160
                $this->fields->chave = $dom->getElementsByTagName('chNFe')->item(0)->nodeValue;
161
                $this->fields->data = $dom->getElementsByTagName('dhEvento')->item(0)->nodeValue;
162
                $this->fields->correcao = $dom->getElementsByTagName('xCorrecao')->item(0)->nodeValue;
163
                $this->fields->conduso = $dom->getElementsByTagName('xCondUso')->item(0)->nodeValue;
164
                if (empty($this->fields->chave)) {
165
                    $this->fields->chave = $dom->getElementsByTagName('chCTe')->item(0)->nodeValue;
166
                }
167
                $this->subject = "Carta de Correção ". $this->config->fantasy;
168
                break;
169
            default:
170
                $type = '';
171
        }
172
        //get email adresses from xml, if exists
173
        //may have one address in <dest><email>
174
        $email = !empty($dom->getElementsByTagName('email')->item(0)->nodeValue) ?
175
            $dom->getElementsByTagName('email')->item(0)->nodeValue : '';
176
        if (! empty($email)) {
177
            $this->addresses[] = $email;
178
        }
179
        //may have others in <obsCont xCampo="email"><xTexto>[email protected]</xTexto>
180
        $obs = $dom->getElementsByTagName('obsCont');
181
        foreach ($obs as $ob) {
182
            if (strtoupper($ob->getAttribute('xCampo')) === 'EMAIL') {
183
                $this->addresses[] = $ob->getElementsByTagName('xTexto')->item(0)->nodeValue;
184
            }
185
        }
186
        //xml may be a NFe or a CTe or a CCe nothing else
187
        if ($type != 'NFe' && $type != 'CTe' && $type != 'CCe') {
188
            $msg = "Você deve passar apenas uma NFe ou um CTe ou um CCe. "
189
                    . "Esse documento não foi reconhecido.";
190
            throw new InvalidArgumentException($msg);
191
        }
192
        $this->type = $type;
193
    }
194
    
195
    
196
    /**
197
     * Set all addresses including those that exists in the xml document
198
     * Send email only to listed addresses ignoring all email addresses in xml
199
     * @param array $addresses
200
     */
201
    protected function setAddresses(array $addresses = [])
202
    {
203
        if (!empty($addresses)) {
204
            $this->addresses = $addresses;
205
        }
206
        $this->removeInvalidAdresses();
207
    }
208
    
209
    /**
210
     * Send mail
211
     * If no parameter was passed, only the email address contained in
212
     * the xml will be used
213
     * @param array $addresses
214
     * @return boolean
215
     * @throws RuntimeException
216
     */
217
    public function send(array $addresses = [])
218
    {
219
        $this->setAddresses($addresses);
220
        if (empty($this->addresses)) {
221
            $msg = 'Não foram passados endereços de email validos !!';
222
            throw new RuntimeException($msg);
223
        }
224
        foreach ($this->addresses as $address) {
225
            $this->mail->addAddress($address);
226
        }
227
        $body = $this->render();
228
        $this->mail->isHTML(true);
229
        $this->mail->Subject = $this->subject;
230
        $this->mail->Body = $body;
231
        $this->mail->AltBody = Html2Text::convert($body);
232
        $this->attach();
233
        if (!$this->mail->send()) {
234
            $msg = 'A mensagem não pode ser enviada. Mail Error: ' . $this->mail->ErrorInfo;
235
            throw new RuntimeException($msg);
236
        }
237
        $this->mail->ClearAllRecipients();
238
        $this->mail->ClearAttachments();
239
        return true;
240
    }
241
    
242
    /**
243
     * Configure and send documents
244
     * @param stdClass $config
245
     * @param type $xml
246
     * @param type $pdf
247
     * @param array $addresses
248
     * @param type $htmltemplate
249
     * @param PHPMailer $mailer
250
     * @return \static
251
     */
252
    public static function sendMail(
253
        stdClass $config,
254
        $xml,
255
        $pdf = '',
256
        array $addresses = [],
257
        $htmltemplate = '',
258
        PHPMailer $mailer = null
259
    ) {
260
        $mail = new static($config, $mailer);
261
        $mail->loadDocuments($xml, $pdf);
262
        $mail->setTemplate($htmltemplate);
263
        $mail->send($addresses);
264
        return $mail;
265
    }
266
}
267