Passed
Pull Request — master (#6)
by
unknown
03:19
created

Email::send()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
cc 2
eloc 3
c 0
b 0
f 0
nc 2
nop 1
dl 0
loc 7
ccs 0
cts 4
cp 0
crap 6
rs 10
1
<?php
2
3
namespace Slides\Connector\Auth\Clients\Mandrill\Builders;
4
5
use Exception;
6
use Illuminate\Support\Collection;
7
use Slides\Connector\Auth\Clients\Mandrill\Mailer;
8
use Slides\Connector\Auth\Clients\Mandrill\VariableResolver;
9
10
/**
11
 * Class Email
12
 *
13
 * @package Slides\Connector\Auth\Clients\Mandrill\Builders
14
 */
15
class Email
16
{
17
    /**
18
     * @var Mailer
19
     */
20
    protected $mailer;
21
22
    /**
23
     * The variable resolver.
24
     *
25
     * @var VariableResolver
26
     */
27
    protected $resolver;
28
29
    /**
30
     * The additional attributes that should be added to email.
31
     *
32
     * @var array
33
     */
34
    protected $attributes = [];
35
36
    /**
37
     * @var string
38
     */
39
    protected $template;
40
41
    /**
42
     * @var array
43
     */
44
    protected $variables;
45
46
    /**
47
     * @var Collection
48
     */
49
    protected $recipients;
50
51
    /**
52
     * Email constructor.
53
     *
54
     * @param Mailer $mailer
55
     * @param VariableResolver $resolver
56
     */
57
    public function __construct(Mailer $mailer, VariableResolver $resolver = null)
58
    {
59
        $this->mailer = $mailer;
60
61
        $this->resolver = $resolver ?: app(config('connector.credentials.clients.mandrill.resolver'));
0 ignored issues
show
Documentation Bug introduced by
It seems like $resolver ?: app(config(...ts.mandrill.resolver')) can also be of type Illuminate\Foundation\Application. However, the property $resolver is declared as type Slides\Connector\Auth\Cl...ndrill\VariableResolver. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

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

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
62
    }
63
64
    /**
65
     * Retrieve recipients.
66
     *
67
     * @return Collection
68
     */
69
    public function getRecipients(): Collection
70
    {
71
        return $this->recipients;
72
    }
73
74
    /**
75
     * Set the email template.
76
     *
77
     * @param string $template
78
     *
79
     * @return $this
80
     */
81
    public function template(string $template)
82
    {
83
        $this->template = $template;
84
85
        return $this;
86
    }
87
88
    /**
89
     * Set additional variables.
90
     *
91
     * @param array $variables
92
     *
93
     * @return $this
94
     */
95
    public function variables(array $variables)
96
    {
97
        $this->variables = $variables;
98
99
        return $this;
100
    }
101
102
    /**
103
     * Set the message subject.
104
     *
105
     * @param string $subject
106
     *
107
     * @return static
108
     */
109
    public function subject(string $subject)
110
    {
111
        $this->attributes['subject'] = $subject;
112
113
        return $this;
114
    }
115
116
    /**
117
     * Set the sender email address and name.
118
     *
119
     * @param string $email
120
     * @param string $name
121
     *
122
     * @return static
123
     */
124
    public function from(string $email, ?string $name = null)
125
    {
126
        $this->attributes['from'] = compact('email', 'name');
127
128
        return $this;
129
    }
130
131
    /**
132
     * Set the email recipients.
133
     *
134
     * @param mixed $recipients
135
     *
136
     * @return static
137
     */
138
    public function recipients($recipients)
139
    {
140
        $this->recipients = collect($recipients);
141
142
        return $this;
143
    }
144
145
    /**
146
     * Chunk the recipients.
147
     *
148
     * @param int $size
149
     *
150
     * @return array
151
     */
152
    public function chunk(int $size = 1000): array
153
    {
154
        $chunks = $this->recipients->chunk($size);
155
156
        return $chunks->map([$this, 'build'])->toArray();
157
    }
158
159
    /**
160
     * Send the email.
161
     *
162
     * @param Collection $recipients
163
     *
164
     * @return mixed
165
     */
166
    public function send(Collection $recipients = null)
167
    {
168
        if (is_null($recipients)) {
169
            $recipients = $this->recipients;
170
        }
171
172
        return $this->mailer->send($this->build($recipients));
173
    }
174
175
    /**
176
     * Chunk recipients before sending.
177
     *
178
     * @param int $size
179
     *
180
     * @return \Generator
181
     */
182
    public function sendChunk(int $size = 1000)
183
    {
184
        foreach ($this->recipients->chunk($size) as $chunk) {
185
            yield $this->send($chunk);
186
        }
187
    }
188
189
    /**
190
     * Build the email to be sent.
191
     *
192
     * @param Collection|null $recipients
193
     *
194
     * @return array
195
     */
196
    protected function build(Collection $recipients): array
197
    {
198
        return array_merge([
199
            'template' => $this->template,
200
            'recipients' => $this->buildRecipients($recipients),
201
            'variables' => $this->buildVariables($recipients),
202
        ], $this->attributes);
203
    }
204
205
    /**
206
     * Build the message recipients.
207
     *
208
     * @param Collection $recipients
209
     *
210
     * @return array
211
     */
212
    protected function buildRecipients(Collection $recipients): array
213
    {
214
        return $recipients->map(function (string $email) {
215
            return [
216
                'email' => $email,
217
                'type' => 'to'
218
            ];
219
        })->toArray();
220
    }
221
222
    /**
223
     * Build the variables for given collection of recipients.
224
     *
225
     * @param Collection $recipients
226
     *
227
     * @return array
228
     */
229
    protected function buildVariables(Collection $recipients): array
230
    {
231
        return $recipients->map(function (string $email) {
232
            return [
233
                'rcpt' => $email,
234
                'vars' => $this->userVariables($email)
235
            ];
236
        })->toArray();
237
    }
238
239
    /**
240
     * Build variable for a user.
241
     *
242
     * @param string $email
243
     *
244
     * @return array
245
     *
246
     * @throws Exception
247
     */
248
    protected function userVariables(string $email): array
249
    {
250
        return array_map(function ($variable) use ($email) {
251
            return $this->resolver->resolve($variable, $email);
252
        }, $this->variables);
253
    }
254
}