Completed
Push — master ( 6c2fe3...ff207a )
by Gabriel
29s
created

Mailjet   B

Complexity

Total Complexity 39

Size/Duplication

Total Lines 190
Duplicated Lines 37.89 %

Coupling/Cohesion

Components 1
Dependencies 7

Test Coverage

Coverage 0%

Importance

Changes 3
Bugs 1 Features 2
Metric Value
wmc 39
c 3
b 1
f 2
lcom 1
cbo 7
dl 72
loc 190
ccs 0
cts 106
cp 0
rs 8.2857

9 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 7 1
D send() 0 54 11
B mapAttachments() 19 19 7
B mapInlineAttachments() 19 19 7
A mapAttachment() 18 18 4
A mapEmails() 0 8 2
A mapEmail() 8 8 2
A mapEmailsString() 8 8 3
A mapEmailString() 0 4 2

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
3
namespace Omnimail;
4
5
use Omnimail\Exception\InvalidRequestException;
6
use Psr\Log\LoggerInterface;
7
use Mailjet\Resources;
8
use Mailjet\Client;
9
10
class Mailjet implements EmailSenderInterface
11
{
12
    private $apikey;
13
    private $apisecret;
14
    private $logger;
15
    private $mailjet;
16
17
    /**
18
     * @param string $apikey
19
     * @param string $apisecret
20
     * @param LoggerInterface|null $logger
21
     */
22
    public function __construct($apikey, $apisecret, LoggerInterface $logger = null)
23
    {
24
        $this->apikey = $apikey;
25
        $this->apisecret = $apisecret;
26
        $this->logger = $logger;
27
        $this->mailjet = new Client($apikey, $apisecret);
28
    }
29
30
    public function send(EmailInterface $email)
31
    {
32
        $from = $email->getFrom();
33
34
        $body = [
35
            'FromEmail' => $from['email'],
36
            'Subject' => $email->getSubject(),
37
            'To' => $this->mapEmails($email->getTos())
38
        ];
39
40
        if (!empty($from['name'])) {
41
            $body['FromName'] = $from['name'];
42
        }
43
44
        if ($email->getReplyTos()) {
45
            $body['Headers'] = [
46
                'Reply-To' => $this->mapEmailsString($email->getReplyTos())
47
            ];
48
        }
49
50
        if ($email->getCcs()) {
51
            $body['Cc'] = $this->mapEmails($email->getCcs());
52
        }
53
54
        if ($email->getBccs()) {
55
            $body['Bcc'] = $this->mapEmails($email->getBccs());
56
        }
57
58
        if ($email->getTextBody()) {
59
            $body['Text-part'] = $email->getTextBody();
60
        }
61
62
        if ($email->getHtmlBody()) {
63
            $body['Html-part'] = $email->getHtmlBody();
64
        }
65
66
        if ($email->getAttachments()) {
67
            $body['Attachments'] = $this->mapAttachments($email->getAttachments());
68
            $body['Inline_attachments'] = $this->mapInlineAttachments($email->getAttachments());
69
        }
70
71
        $response = $this->mailjet->post(Resources::$Email, ['body' => $body]);
72
73
        if ($response->success()) {
74
            if ($this->logger) {
75
                $this->logger->info("Email sent: '{$email->getSubject()}'", $email);
0 ignored issues
show
Documentation introduced by
$email is of type object<Omnimail\EmailInterface>, but the function expects a array.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
76
            }
77
        } else {
78
            if ($this->logger) {
79
                $this->logger->error("Email error: '{$response->getReasonPhrase()}'", $email);
0 ignored issues
show
Documentation introduced by
$email is of type object<Omnimail\EmailInterface>, but the function expects a array.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
80
            }
81
            throw new InvalidRequestException($response->getReasonPhrase());
82
        }
83
    }
84
85
    /**
86
     * @param array|null $attachments
87
     * @return array|null
88
     */
89 View Code Duplication
    private function mapAttachments(array $attachments)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
90
    {
91
        if (null === $attachments || !is_array($attachments) || !count($attachments)) {
92
            return null;
93
        }
94
95
        $finalAttachments = [];
96
        /** @var AttachmentInterface $attachment */
97
        foreach ($attachments as $attachment) {
98
            if ($attachment->getContentId()) {
99
                continue;
100
            }
101
            $finalAttachment = $this->mapAttachment($attachment);
102
            if ($finalAttachment) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $finalAttachment of type array<string,string|null> is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
103
                $finalAttachments[] = $finalAttachment;
104
            }
105
        }
106
        return $finalAttachments;
107
    }
108
109
    /**
110
     * @param array|null $attachments
111
     * @return array|null
112
     */
113 View Code Duplication
    private function mapInlineAttachments(array $attachments)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
114
    {
115
        if (null === $attachments || !is_array($attachments) || !count($attachments)) {
116
            return null;
117
        }
118
119
        $finalAttachments = [];
120
        /** @var AttachmentInterface $attachment */
121
        foreach ($attachments as $attachment) {
122
            if (!$attachment->getContentId()) {
123
                continue;
124
            }
125
            $finalAttachment = $this->mapAttachment($attachment);
126
            if ($finalAttachment) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $finalAttachment of type array<string,string|null> is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
127
                $finalAttachments[] = $finalAttachment;
128
            }
129
        }
130
        return $finalAttachments;
131
    }
132
133 View Code Duplication
    private function mapAttachment(AttachmentInterface $attachment)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
134
    {
135
        $finalAttachment = [
136
            'Content-type' => $attachment->getMimeType(),
137
            'Filename' => $attachment->getName()
138
        ];
139
        if ($attachment->getPath()) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $attachment->getPath() of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
140
            $finalAttachment['content'] = base64_encode(file_get_contents($attachment->getPath()));
141
        } elseif ($attachment->getContent()) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $attachment->getContent() of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
142
            $finalAttachment['content'] = base64_encode($attachment->getContent());
143
        }
144
145
        if ($attachment->getContentId()) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $attachment->getContentId() of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
146
            $finalAttachment['Filename'] = $attachment->getContentId();
147
        }
148
149
        return $finalAttachment;
150
    }
151
152
    /**
153
     * @param array $emails
154
     * @return array
155
     */
156
    private function mapEmails(array $emails)
157
    {
158
        $returnValue = [];
159
        foreach ($emails as $email) {
160
            $returnValue[] = $this->mapEmail($email);
161
        }
162
        return $returnValue;
163
    }
164
165
    /**
166
     * @param array $email
167
     * @return array
168
     */
169 View Code Duplication
    private function mapEmail(array $email)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
170
    {
171
        $returnValue = ['Email' => $email['email']];
172
        if ($email['name']) {
173
            $returnValue['Name'] = $email['name'];
174
        }
175
        return $returnValue;
176
    }
177
178
    /**
179
     * @param array $emails
180
     * @return string
181
     */
182 View Code Duplication
    private function mapEmailsString(array $emails)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
183
    {
184
        $returnValue = '';
185
        foreach ($emails as $email) {
186
            $returnValue .= $this->mapEmailString($email) . ', ';
187
        }
188
        return $returnValue ? substr($returnValue, 0, -2) : '';
189
    }
190
191
    /**
192
     * @param array $email
193
     * @return string
194
     */
195
    private function mapEmailString(array $email)
196
    {
197
        return !empty($email['name']) ? "'{$email['name']}' <{$email['email']}>" : $email['email'];
198
    }
199
}
200