Test Failed
Push — master ( 321e41...d641b2 )
by Jan
02:14
created

Webhook::setIsTts()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 2
c 0
b 0
f 0
dl 0
loc 5
rs 10
cc 1
nc 1
nop 1
1
<?php
2
declare(strict_types=1);
3
4
namespace DiscordWebhook;
5
6
use Doctrine\Common\Collections\ArrayCollection;
7
use GuzzleHttp\Client;
8
use GuzzleHttp\Exception\GuzzleException;
9
use RuntimeException;
10
use SplFileInfo;
11
use Symfony\Component\Serializer\Annotation\Groups;
12
use Symfony\Component\Serializer\Annotation\SerializedName;
13
14
/**
15
 * Class Webhook
16
 *
17
 * @author Scrummer <[email protected]>
18
 * @package DiscordWebhook
19
 */
20
class Webhook implements WebhookInterface
21
{
22
    /**
23
     * @var Client[]|ArrayCollection
24
     */
25
    private $clients;
26
27
    /**
28
     * @var string
29
     *
30
     * @Groups({"discord"})
31
     */
32
    private $username;
33
34
    /**
35
     * @var string
36
     *
37
     * @Groups({"discord"})
38
     * @SerializedName("avatar_url")
39
     */
40
    private $avatar;
41
42
    /**
43
     * @var string
44
     *
45
     * @Groups({"discord"})
46
     */
47
    private $message;
48
49
    /**
50
     * @var bool
51
     *
52
     * @Groups({"discord"})
53
     * @SerializedName("tts")
54
     */
55
    private $isTts;
56
57
    /**
58
     * @var SplFileInfo
59
     *
60
     * @Groups({"discord"})
61
     */
62
    private $file;
63
64
    /**
65
     * @var Embed[]|ArrayCollection
66
     *
67
     * @Groups({"discord"})
68
     */
69
    private $embeds;
70
71
    /**
72
     * Constructor.
73
     *
74
     * @param array $url
75
     */
76
    public function __construct(array $url)
77
    {
78
        $this->embeds = new ArrayCollection();
79
        $this->clients = new ArrayCollection();
80
81
        foreach ($url as $webhook) {
82
            $this->clients->add(new Client([
83
                'base_uri' => $webhook
84
            ]));
85
        }
86
    }
87
88
    /**
89
     * Send the Webhook
90
     *
91
     * @return bool
92
     */
93
    public function send(): bool
94
    {
95
        /** @var int[] $responseCodes */
96
        $responseCodes = [];
97
        $payload = $this->buildPayload();
98
99
        $this->clients->forAll(static function (int $key, Client $client) use ($payload) {
100
            $responseCodes[] = $client->request(
0 ignored issues
show
Comprehensibility Best Practice introduced by
$responseCodes was never initialized. Although not strictly required by PHP, it is generally a good practice to add $responseCodes = array(); before regardless.
Loading history...
101
                'POST',
102
                $client->getConfig('base_uri')->getPath(),
103
                $payload
104
            )->getStatusCode();
105
        });
106
107
        foreach ($responseCodes as $responseCode) {
108
            if (!in_array($responseCode, [200, 201, 202, 204], true)) {
109
                return false;
110
            }
111
        }
112
113
        return true;
114
    }
115
116
    private function buildPayload(): array
117
    {
118
119
120
121
        // ==============================
122
        $fields = [
123
            'username' => 'username',
124
            'avatar'   => 'avatar_url',
125
            'message'  => 'content',
126
            'tts'      => 'tts',
127
            'file'     => 'file',
128
            'embeds'   => 'embeds'
129
        ];
130
        $payload = [
131
            'multipart' => []
132
        ];
133
134
        foreach ($fields as $field => $payloadField) {
135
            if (!property_exists($this, $field) || null === $this->$field) {
136
                continue;
137
            }
138
139
            if (is_string($this->$field) || is_bool($this->$field)) { // add string and booloan values
140
                $payload['multipart'][] = [
141
                    'name'     => $payloadField,
142
                    'contents' => $this->$field
143
                ];
144
            } elseif ($this->$field instanceof SplFileInfo) { // add file
145
                /** @var SplFileInfo $file */
146
                $file = $this->$field;
147
148
                $payload['multipart'][] = [
149
                    'name'     => $payloadField,
150
                    'contents' => $file->openFile()->fread($file->getSize()),
151
                    'filename' => $file->getFilename()
152
                ];
153
            }
154
        }
155
156
        return $payload;
157
    }
158
159
    /**
160
     * @param bool $isTts
161
     *
162
     * @return WebhookInterface
163
     */
164
    public function setIsTts(bool $isTts = false): WebhookInterface
165
    {
166
        $this->isTts = $isTts;
167
168
        return $this;
169
    }
170
171
    /**
172
     * @param string $username
173
     *
174
     * @return WebhookInterface
175
     */
176
    public function setUsername(string $username): WebhookInterface
177
    {
178
        $this->username = $username;
179
180
        return $this;
181
    }
182
183
    /**
184
     * @param string $url
185
     *
186
     * @return WebhookInterface
187
     */
188
    public function setAvatar(string $url): WebhookInterface
189
    {
190
        $this->avatar = $url;
191
192
        return $this;
193
    }
194
195
    /**
196
     * @param string $message
197
     *
198
     * @return WebhookInterface
199
     */
200
    public function setMessage(string $message): WebhookInterface
201
    {
202
        $this->message = $message;
203
204
        return $this;
205
    }
206
207
    /**
208
     * @param SplFileInfo $file
209
     *
210
     * @return WebhookInterface
211
     */
212
    public function setFile(SplFileInfo $file): WebhookInterface
213
    {
214
        $this->file = $file;
215
216
        return $this;
217
    }
218
219
    /**
220
     * Add an embed to the message.
221
     *
222
     * @param Embed $embed
223
     *
224
     * @return int The index of the recently added embed
225
     */
226
    public function addEmbed(Embed $embed): int
227
    {
228
        if ($this->embeds->count() >= Embed::CONFIG_MAX_COUNT) {
229
            throw new RuntimeException(sprintf('Maximum amount of embeds reached for this message. Discord allows only %d embeds.', Embed::CONFIG_MAX_COUNT));
230
        }
231
232
        $this->embeds->add($embed);
233
234
        return (int)$this->embeds->indexOf($embed);
235
    }
236
}
237