Completed
Push — master ( f040ca...690db4 )
by Roberto
05:32 queued 02:31
created

Mail::loadTemplate()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 6
ccs 4
cts 4
cp 1
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 3
nc 2
nop 1
crap 2
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
     * Html Body mail message
31
     * @var string
32
     */
33
    public $body;
34
    /**
35
     * Subject for email
36
     * @var string
37
     */
38
    public $subject;
39
    
40
    /**
41
     * Constructor
42
     * @param \stdClass $config
43
     */
44
    public function __construct(stdClass $config, PHPMailer $mailer = null)
45
    {
46
        $this->mail = $mailer;
47
        if (is_null($mailer)) {
48
            $this->mail = new PHPMailer();
49
        }
50
        $this->config = $config;
0 ignored issues
show
Documentation Bug introduced by
It seems like $config of type object<stdClass> is incompatible with the declared type object<NFePHP\Mail\stdClass> of property $config.

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