EnvelopeFactory::createMessage()   C
last analyzed

Complexity

Conditions 10
Paths 192

Size

Total Lines 74
Code Lines 34

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 110

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 10
eloc 34
c 1
b 0
f 0
nc 192
nop 2
dl 0
loc 74
ccs 0
cts 38
cp 0
crap 110
rs 6.9

How to fix   Long Method    Complexity   

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
declare(strict_types=1);
4
5
/**
6
 * Derafu: Biblioteca PHP (Núcleo).
7
 * Copyright (C) Derafu <https://www.derafu.org>
8
 *
9
 * Este programa es software libre: usted puede redistribuirlo y/o modificarlo
10
 * bajo los términos de la Licencia Pública General Affero de GNU publicada por
11
 * la Fundación para el Software Libre, ya sea la versión 3 de la Licencia, o
12
 * (a su elección) cualquier versión posterior de la misma.
13
 *
14
 * Este programa se distribuye con la esperanza de que sea útil, pero SIN
15
 * GARANTÍA ALGUNA; ni siquiera la garantía implícita MERCANTIL o de APTITUD
16
 * PARA UN PROPÓSITO DETERMINADO. Consulte los detalles de la Licencia Pública
17
 * General Affero de GNU para obtener una información más detallada.
18
 *
19
 * Debería haber recibido una copia de la Licencia Pública General Affero de GNU
20
 * junto a este programa.
21
 *
22
 * En caso contrario, consulte <http://www.gnu.org/licenses/agpl.html>.
23
 */
24
25
namespace Derafu\Lib\Core\Package\Prime\Component\Mail\Factory;
26
27
use DateTimeImmutable;
28
use Derafu\Lib\Core\Package\Prime\Component\Mail\Contract\EnvelopeInterface;
29
use Derafu\Lib\Core\Package\Prime\Component\Mail\Contract\MessageInterface;
30
use Derafu\Lib\Core\Package\Prime\Component\Mail\Support\Envelope;
31
use Derafu\Lib\Core\Package\Prime\Component\Mail\Support\Message;
32
use PhpImap\IncomingMail;
33
use PhpImap\IncomingMailAttachment;
34
use Symfony\Component\Mime\Address;
35
36
/**
37
 * Fábrica para crear un objeto Envelope a partir de una instancia de Mail.
38
 */
39
class EnvelopeFactory
40
{
41
    /**
42
     * Crea el sobre a partir de los datos de un correo entrante.
43
     *
44
     * @param IncomingMail $mail
45
     * @param array $attachmentFilters
46
     * @return EnvelopeInterface
47
     */
48
    public function createFromIncomingMail(
49
        IncomingMail $mail,
50
        array $attachmentFilters = []
51
    ): EnvelopeInterface {
52
        // Determinar quién envía el correo.
53
        if (!empty($mail->senderAddress)) {
54
            $senderAddress = $mail->senderAddress;
55
            $senderName = $mail->senderName ?? '';
56
        } else {
57
            $senderAddress = $mail->fromAddress;
58
            $senderName = $mail->fromName ?? '';
59
        }
60
61
        // Crear el listado completo con receptores del correo.
62
        $recipients = array_merge($mail->to, $mail->cc, $mail->bcc);
63
64
        // Crear el sobre.
65
        $envelope = new Envelope(
66
            new Address($senderAddress, $senderName),
0 ignored issues
show
Bug introduced by
It seems like $senderAddress can also be of type null; however, parameter $address of Symfony\Component\Mime\Address::__construct() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

66
            new Address(/** @scrutinizer ignore-type */ $senderAddress, $senderName),
Loading history...
67
            array_map(
68
                fn ($email, $name) => new Address($email, $name ?? ''),
69
                array_keys($recipients),
70
                $recipients
71
            )
72
        );
73
74
        // Crear el mensaje y agregarlo al sobre.
75
        $message = $this->createMessage($mail, $attachmentFilters);
76
        $envelope->addMessage($message);
77
78
        // Retornar el sobre con el mensaje.
79
        return $envelope;
80
    }
81
82
    /**
83
     * Crea el mensaje a partir de los datos de un correo entrante.
84
     *
85
     * @param IncomingMail $mail
86
     * @param array $attachmentFilters
87
     * @return MessageInterface
88
     */
89
    private function createMessage(
90
        IncomingMail $mail,
91
        array $attachmentFilters = []
92
    ): MessageInterface {
93
        // Crear el mensaje.
94
        $message = new Message();
95
96
        // Agregar el ID del mensaje (en el contexto del transporte).
97
        $message->id($mail->id);
0 ignored issues
show
Bug introduced by
It seems like $mail->id can also be of type null; however, parameter $id of Derafu\Lib\Core\Package\...l\Support\Message::id() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

97
        $message->id(/** @scrutinizer ignore-type */ $mail->id);
Loading history...
98
99
        // Agregar la fecha del mensaje.
100
        $message->date(new DateTimeImmutable($mail->date));
101
102
        // Agregar remitente.
103
        $message->from(new Address($mail->fromAddress, $mail->fromName ?? ''));
0 ignored issues
show
Bug introduced by
It seems like $mail->fromAddress can also be of type null; however, parameter $address of Symfony\Component\Mime\Address::__construct() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

103
        $message->from(new Address(/** @scrutinizer ignore-type */ $mail->fromAddress, $mail->fromName ?? ''));
Loading history...
104
105
        // Agregar destinatarios principales (TO).
106
        if (!empty($mail->to)) {
107
            $message->to(...array_map(
108
                fn ($email, $name) => new Address($email, $name ?? ''),
109
                array_keys($mail->to),
110
                $mail->to
111
            ));
112
        }
113
114
        // Agregar destinatarios en copia (CC).
115
        if (!empty($mail->cc)) {
116
            $message->cc(...array_map(
117
                fn ($email, $name) => new Address($email, $name ?? ''),
118
                array_keys($mail->cc),
119
                $mail->cc
120
            ));
121
        }
122
123
        // Agregar destinatarios ocultos (BCC).
124
        if (!empty($mail->bcc)) {
125
            $message->bcc(...array_map(
126
                fn ($email, $name) => new Address($email, $name ?? ''),
127
                array_keys($mail->bcc),
128
                $mail->bcc
129
            ));
130
        }
131
132
        // Agregar asunto.
133
        if (!empty($mail->subject)) {
134
            $message->subject($mail->subject);
135
        }
136
137
        // Agregar cuerpo del mensaje como texto plano.
138
        if (!empty($mail->textPlain)) {
139
            $message->text($mail->textPlain);
140
        }
141
142
        // Agregar cuerpo del mensaje como HTML.
143
        if (!empty($mail->textHtml)) {
144
            $message->html($mail->textHtml);
145
        }
146
147
        // Agregar los archivos adjuntos si existen.
148
        foreach ($mail->getAttachments() as $attachment) {
149
            if (
150
                !$attachmentFilters
151
                || $this->attachmentPassFilters($attachment, $attachmentFilters)
152
            ) {
153
                $message->attach(
154
                    $attachment->getContents(),
155
                    $attachment->name,
156
                    $attachment->mimeType
157
                );
158
            }
159
        }
160
161
        // Entregar el mensaje del correo electrónico.
162
        return $message;
163
    }
164
165
    /**
166
     * Aplica los filtros a una parte del mensaje.
167
     *
168
     * @param IncomingMailAttachment $attachment Parte del mensaje a filtrar.
169
     * @param array $filters Filtros a usar.
170
     * @return bool `true` si la parte del mensaje pasa los filtros, `false` en
171
     * caso contrario.
172
     */
173
    private function attachmentPassFilters(
174
        IncomingMailAttachment $attachment,
175
        array $filters
176
    ): bool {
177
        // Filtrar por: subtype.
178
        if (!empty($filters['subtype'])) {
179
            $subtype = strtoupper($attachment->subtype);
0 ignored issues
show
Bug introduced by
It seems like $attachment->subtype can also be of type null; however, parameter $string of strtoupper() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

179
            $subtype = strtoupper(/** @scrutinizer ignore-type */ $attachment->subtype);
Loading history...
180
            $subtypes = array_map('strtoupper', $filters['subtype']);
181
            if (!in_array($subtype, $subtypes)) {
182
                return false;
183
            }
184
        }
185
186
        // Filtrar por: extension.
187
        if (!empty($filters['extension'])) {
188
            $extension = strtolower(pathinfo(
0 ignored issues
show
Bug introduced by
It seems like pathinfo($attachment->na...ory\PATHINFO_EXTENSION) can also be of type array; however, parameter $string of strtolower() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

188
            $extension = strtolower(/** @scrutinizer ignore-type */ pathinfo(
Loading history...
189
                $attachment->name,
0 ignored issues
show
Bug introduced by
It seems like $attachment->name can also be of type null; however, parameter $path of pathinfo() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

189
                /** @scrutinizer ignore-type */ $attachment->name,
Loading history...
190
                PATHINFO_EXTENSION
191
            ));
192
            $extensions = array_map('strtolower', $filters['extension']);
193
            if (!in_array($extension, $extensions)) {
194
                return false;
195
            }
196
        }
197
198
        // Pasó los filtros ok.
199
        return true;
200
    }
201
}
202