Test Failed
Push — master ( ac51f2...88d110 )
by Jan
03:50
created

Webhook::addEmbed()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 4
c 1
b 0
f 0
dl 0
loc 9
rs 10
cc 2
nc 2
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
12
/**
13
 * Class Webhook
14
 *
15
 * @author Scrummer <[email protected]>
16
 * @package DiscordWebhook
17
 */
18
class Webhook implements WebhookInterface
19
{
20
    /**
21
     * @var Client
22
     */
23
    private $client;
24
25
    /**
26
     * @var string
27
     */
28
    private $username;
29
30
    /**
31
     * @var string
32
     */
33
    private $avatar;
34
35
    /**
36
     * @var string
37
     */
38
    private $message;
39
40
    /**
41
     * @var bool
42
     */
43
    private $tts;
44
45
    /**
46
     * @var SplFileInfo
47
     */
48
    private $file;
49
50
    /**
51
     * @var Embed[]|ArrayCollection
52
     */
53
    private $embeds;
54
55
    /**
56
     * Constructor.
57
     *
58
     * @param string $url
59
     */
60
    public function __construct(string $url)
61
    {
62
        $this->embeds = new ArrayCollection();
63
        $this->client = new Client([
64
            'base_uri' => $url
65
        ]);
66
    }
67
68
    /**
69
     * Send the Webhook
70
     *
71
     * @return bool
72
     * @throws GuzzleException
73
     */
74
    public function send(): bool
75
    {
76
        $response = $this->client->request(
77
            'POST',
78
            $this->client->getConfig('base_uri')->getPath(),
79
            $this->buildPayload()
80
        );
81
82
        return in_array($response->getStatusCode(), [200, 201, 202, 204], true);
83
    }
84
85
    private function buildPayload(): array
86
    {
87
        $fields  = [
88
            'username' => 'username',
89
            'avatar'   => 'avatar_url',
90
            'message'  => 'content',
91
            'tts'      => 'tts',
92
            'file'     => 'file',
93
            'embeds'   => 'embeds'
94
        ];
95
        $payload = [
96
            'multipart' => []
97
        ];
98
99
        foreach ($fields as $field => $payloadField) {
100
            if (!property_exists($this, $field) || null === $this->$field) {
101
                continue;
102
            }
103
104
            if (is_string($this->$field) || is_bool($this->$field)) { // add string and booloan values
105
                $payload['multipart'][] = [
106
                    'name'     => $payloadField,
107
                    'contents' => $this->$field
108
                ];
109
            } elseif ($this->$field instanceof SplFileInfo) { // add file
110
                /** @var SplFileInfo $file */
111
                $file = $this->$field;
112
113
                $payload['multipart'][] = [
114
                    'name'     => $payloadField,
115
                    'contents' => $file->openFile()->fread($file->getSize()),
116
                    'filename' => $file->getFilename()
117
                ];
118
            }
119
        }
120
121
        return $payload;
122
    }
123
124
    /**
125
     * @param bool $tts
126
     *
127
     * @return WebhookInterface
128
     */
129
    public function setTts(bool $tts = false): WebhookInterface
130
    {
131
        $this->tts = $tts;
132
133
        return $this;
134
    }
135
136
    /**
137
     * @param string $username
138
     *
139
     * @return WebhookInterface
140
     */
141
    public function setUsername(string $username): WebhookInterface
142
    {
143
        $this->username = $username;
144
145
        return $this;
146
    }
147
148
    /**
149
     * @param string $url
150
     *
151
     * @return WebhookInterface
152
     */
153
    public function setAvatar(string $url): WebhookInterface
154
    {
155
        $this->avatar = $url;
156
157
        return $this;
158
    }
159
160
    /**
161
     * @param string $message
162
     *
163
     * @return WebhookInterface
164
     */
165
    public function setMessage(string $message): WebhookInterface
166
    {
167
        $this->message = $message;
168
169
        return $this;
170
    }
171
172
    /**
173
     * @param SplFileInfo $file
174
     *
175
     * @return WebhookInterface
176
     */
177
    public function setFile(SplFileInfo $file): WebhookInterface
178
    {
179
        $this->file = $file;
180
181
        return $this;
182
    }
183
184
    /**
185
     * Add an embed to the message.
186
     *
187
     * @param Embed $embed
188
     *
189
     * @return int The index of the recently added embed
190
     */
191
    public function addEmbed(Embed $embed): int
192
    {
193
        if ($this->embeds->count() >= Embed::CONFIG_MAX_COUNT) {
194
            throw new RuntimeException(sprintf('Maximum amount of embeds reached for this message. Discord allows only %d embeds.', Embed::CONFIG_MAX_COUNT));
195
        }
196
197
        $this->embeds->add($embed);
198
199
        return (int)$this->embeds->indexOf($embed);
200
    }
201
}
202