Completed
Pull Request — devel (#2)
by
unknown
38:16
created

Mailer::sendMultiple()   C

Complexity

Conditions 9
Paths 50

Size

Total Lines 60
Code Lines 30

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 60
rs 6.8358
c 0
b 0
f 0
cc 9
eloc 30
nc 50
nop 2

How to fix   Long Method   

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
 * Mail.php
4
 *
5
 * PHP version 5.6+
6
 *
7
 * @author Philippe Gaultier <[email protected]>
8
 * @copyright 2010-2017 Philippe Gaultier
9
 * @license http://www.sweelix.net/license license
10
 * @version XXX
11
 * @link http://www.sweelix.net
12
 * @package sweelix\mailjet
13
 */
14
15
namespace sweelix\mailjet;
16
17
18
use Mailjet\Client;
19
use Mailjet\Resources;
20
use yii\base\InvalidConfigException;
21
use yii\helpers\ArrayHelper;
22
use yii\mail\BaseMailer;
23
24
/**
25
 * This component allow user to send an email
26
 *
27
 * @author Philippe Gaultier <[email protected]>
28
 * @copyright 2010-2017 Philippe Gaultier
29
 * @license http://www.sweelix.net/license license
30
 * @version XXX
31
 * @link http://www.sweelix.net
32
 * @package sweelix\mailjet
33
 * @since XXX
34
 */
35
class Mailer extends BaseMailer
36
{
37
    /**
38
     * @var string
39
     */
40
    public $apiKey;
41
42
    /**
43
     * @var string
44
     */
45
    public $apiSecret;
46
47
    /**
48
     * @var boolean
49
     */
50
    public $enable = true;
51
52
    /**
53
     * @var string
54
     */
55
    public $apiVersion = 'v3.1';
56
57
    /**
58
     * @var string
59
     */
60
    public $apiUrl;
61
62
    /**
63
     * @var bool
64
     */
65
    public $secured = true;
66
67
    /**
68
     * @var \Mailjet\Response
69
     */
70
    public $apiResponse;
71
72
    /**
73
     * @inheritdoc
74
     */
75
    public $messageClass = 'sweelix\mailjet\Message';
76
77
78
    /**
79
     * Sends the specified message.
80
     * @param Message $message
81
     * @since XXX
82
     * @throws InvalidConfigException
83
     */
84
    public function sendMessage($message)
85
    {
86
        $messages = [$message];
87
        $result = $this->sendMultiple($messages);
88
        return ($result == 1);
89
    }
90
91
    /**
92
     * Sends multiple messages at once.
93
     * @param Message[] $messages list of email messages, which should be sent.
94
     * @param boolean $returnResponse whether to return the count of successfully sent messages or MailJet's response object
95
     * @return int|\Mailjet\Response number of successfully sent messages, or MailJet's api response if $returnResponse is set to true
96
     * @throws InvalidConfigException
97
     * @todo implement workaround for MailJet's limit of max. 50 recipients (mail addresses?) per API call
98
     */
99
    public function sendMultiple(array $messages, $returnResponse = false)
100
    {
101
        $mailJetMessages = [];
102
        foreach ($messages as $message) {
103
            $mailJetMessages[] = $message->getMailJetMessage();
104
        }
105
106
        try {
107
            if ($this->apiKey === null) {
108
                throw new InvalidConfigException('API Key is missing');
109
            }
110
            if ($this->apiSecret === null) {
111
                throw new InvalidConfigException('API Secret is missing');
112
            }
113
            $settings = [
114
                'secured' => $this->secured,
115
                'version' => $this->apiVersion,
116
            ];
117
118
            if ($this->apiUrl !== null) {
119
                $settings['url'] = $this->apiUrl;
120
            }
121
122
            $client = new Client($this->apiKey, $this->apiSecret, $this->enable, $settings);
123
124
            $this->apiResponse = $client->post(Resources::$Email, [
125
                'body' => [
126
                    'Messages' => $mailJetMessages,
127
                ]
128
            ]);
129
130
            //TODO: handle error codes and log stuff
131
132
            if ($returnResponse) {
133
                return $this->apiResponse;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this->apiResponse; (Mailjet\Response) is incompatible with the return type declared by the interface yii\mail\MailerInterface::sendMultiple of type integer.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
134
            }
135
136
            // count successfully sent messages using MailJet's response
137
            // the format of the response body is:
138
            // ['Messages' => [
139
            //     0 => ['Status' => 'success', ...],
140
            //     1 => ['Status' => 'success', ...],
141
            //     ...
142
            // ]]
143
            $successCount = 0;
144
            $resultBody = $this->apiResponse->getBody();
145
            if ( ! empty($resultBody['Messages'])) {
146
                $resultStatusColumns = ArrayHelper::getColumn($resultBody['Messages'], 'Status');
147
                $statusCounts = array_count_values($resultStatusColumns);
148
                if (isset($statusCounts['success'])) {
149
                    $successCount = $statusCounts['success'];
150
                }
151
            }
152
153
            return $successCount;
154
155
        } catch (InvalidConfigException $e) {
156
            throw $e;
157
        }
158
    }
159
}
160