Skip to content

Commit c95838a

Browse files
authored
Part::save() (#1426)
1 parent d931dc5 commit c95838a

34 files changed

+484
-67
lines changed

src/Discord/Builders/MessageBuilder.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -431,7 +431,6 @@ public function getForward(): ?Message
431431
*/
432432
public function addComponent(ComponentObject $component): self
433433
{
434-
435434
/*
436435
if (! in_array($component::USAGE, ['Message'])) {
437436
throw new \InvalidArgumentException('Invalid component type for messages.');

src/Discord/Discord.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ class Discord
109109
*
110110
* @var string Version.
111111
*/
112-
public const VERSION = 'v10.37.4';
112+
public const VERSION = 'v10.38.0';
113113

114114
public const REFERRER = 'https://github.com/discord-php/DiscordPHP';
115115

src/Discord/DiscordCommandClient.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ public function __construct(array $options = [])
7979
}
8080

8181
if ($withoutPrefix = $this->checkForPrefix($message->content)) {
82-
$args = str_getcsv($withoutPrefix, ' ', '"', "\\");
82+
$args = str_getcsv($withoutPrefix, ' ', '"', '\\');
8383
$command = array_shift($args);
8484

8585
if (null !== $command && $this->commandClientOptions['caseInsensitiveCommands']) {

src/Discord/Parts/Channel/Channel.php

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,15 @@
2424
use Discord\Parts\User\User;
2525
use Discord\Repository\Channel\MessageRepository;
2626
use Discord\Repository\Channel\OverwriteRepository;
27-
use Discord\Repository\Channel\VoiceMemberRepository as MemberRepository;
2827
use Discord\Repository\Channel\WebhookRepository;
2928
use Discord\Helpers\Multipart;
3029
use Discord\Http\Endpoint;
3130
use Discord\Http\Exceptions\NoPermissionsException;
3231
use Discord\Parts\Channel\Forum\Reaction;
3332
use Discord\Parts\Channel\Forum\Tag;
33+
use Discord\Parts\Guild\Guild;
3434
use Discord\Parts\Thread\Thread;
35+
use Discord\Parts\WebSockets\VoiceStateUpdate;
3536
use Discord\Repository\Channel\InviteRepository;
3637
use Discord\Repository\Channel\StageInstanceRepository;
3738
use Discord\Repository\Channel\ThreadRepository;
@@ -194,7 +195,6 @@ class Channel extends Part implements Stringable
194195
*/
195196
protected $repositories = [
196197
'overwrites' => OverwriteRepository::class,
197-
'members' => MemberRepository::class,
198198
'messages' => MessageRepository::class,
199199
'webhooks' => WebhookRepository::class,
200200
'threads' => ThreadRepository::class,
@@ -997,6 +997,21 @@ public function startThread(array|string $options, string|bool|null $reason = nu
997997
return $threadPart;
998998
});
999999
}
1000+
1001+
/**
1002+
* Gets the members currently in the voice channel.
1003+
*
1004+
* @return ExCollectionInterface<VoiceStateUpdate>|VoiceStateUpdate[] Members in the voice channel.
1005+
*/
1006+
public function getMembersAttribute(): ExCollectionInterface
1007+
{
1008+
if ($guild = $this->guild) {
1009+
return $guild->voice_states->filter(fn (VoiceStateUpdate $voice_state) => $voice_state->channel_id === $this->id);
1010+
}
1011+
1012+
return Collection::for(VoiceStateUpdate::class, 'user_id');
1013+
}
1014+
10001015
/**
10011016
* @inheritDoc
10021017
*
@@ -1168,6 +1183,28 @@ public function getUpdatableAttributes(): array
11681183
return $attr;
11691184
}
11701185

1186+
/**
1187+
* @inheritDoc
1188+
*/
1189+
public function save(?string $reason = null): PromiseInterface
1190+
{
1191+
if (isset($this->attributes['guild_id'])) {
1192+
if ($botperms = $this->getBotPermissions()) {
1193+
if (! $botperms->manage_channels) {
1194+
return reject(new NoPermissionsException("You do not have permission to manage channels in the guild {$this->attributes['guild_id']}."));
1195+
}
1196+
}
1197+
/** @var Guild $guild */
1198+
$guild = $this->guild ?? $this->factory->part(Guild::class, ['id' => $this->attributes['guild_id']], true);
1199+
1200+
return $guild->channels->save($this, $reason);
1201+
} elseif ($this->created && $this->discord->private_channels->get('id', $this->id)) {
1202+
return $this->discord->private_channels->save($this, $reason);
1203+
}
1204+
1205+
return parent::save($reason);
1206+
}
1207+
11711208
/**
11721209
* @inheritDoc
11731210
*/

src/Discord/Parts/Channel/Invite.php

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,18 @@
1414
namespace Discord\Parts\Channel;
1515

1616
use Carbon\Carbon;
17+
use Discord\Http\Exceptions\NoPermissionsException;
1718
use Discord\Parts\Guild\Guild;
1819
use Discord\Parts\Guild\Profile;
1920
use Discord\Parts\Guild\ScheduledEvent;
2021
use Discord\Parts\OAuth\Application;
2122
use Discord\Parts\Part;
2223
use Discord\Parts\User\User;
24+
use React\Promise\PromiseInterface;
2325
use Stringable;
2426

27+
use function React\Promise\reject;
28+
2529
/**
2630
* An invite to a Channel and Guild.
2731
*
@@ -117,9 +121,11 @@ protected function getIdAttribute(): string
117121
*/
118122
protected function getGuildAttribute(): ?Guild
119123
{
120-
$guildId = $this->guild_id;
124+
if (! isset($this->attributes['guild_id'])) {
125+
return null;
126+
}
121127

122-
if ($guildId && $guild = $this->discord->guilds->get('id', $guildId)) {
128+
if ($guild = $this->discord->guilds->get('id', $this->attributes['guild_id'])) {
123129
return $guild;
124130
}
125131

@@ -308,6 +314,26 @@ protected function getInviteUrlAttribute(): string
308314
return 'https://discord.gg/'.$this->code;
309315
}
310316

317+
/**
318+
* @inheritDoc
319+
*/
320+
public function save(?string $reason = null): PromiseInterface
321+
{
322+
if (isset($this->attributes['channel_id'])) {
323+
/** @var Channel $channel */
324+
$channel = $this->channel ?? $this->factory->part(Channel::class, ['id' => $this->attributes['channel_id']], true);
325+
if ($botperms = $channel->getBotPermissions()) {
326+
if (! $botperms->create_instant_invite) {
327+
return reject(new NoPermissionsException("You do not have permission to create invites in the channel {$channel->id}."));
328+
}
329+
}
330+
331+
return $channel->invites->save($this, $reason);
332+
}
333+
334+
return parent::save();
335+
}
336+
311337
/**
312338
* @inheritDoc
313339
*/

src/Discord/Parts/Channel/Message.php

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1387,6 +1387,41 @@ public function getUpdatableAttributes(): array
13871387
];
13881388
}
13891389

1390+
/**
1391+
* @inheritDoc
1392+
*/
1393+
public function save(?string $reason = null): PromiseInterface
1394+
{
1395+
if (isset($this->attributes['channel_id'])) {
1396+
/** @var Channel $channel */
1397+
$channel = $this->channel ?? $this->factory->part(Channel::class, ['id' => $this->attributes['channel_id']], true);
1398+
1399+
if ($botperms = $channel->getBotPermissions()) {
1400+
if (! $this->created) {
1401+
if (! $botperms->send_messages) {
1402+
return reject(new NoPermissionsException("You do not have permission to send messages in channel {$channel->id}."));
1403+
}
1404+
}
1405+
if (! $botperms->manage_messages) {
1406+
return reject(new NoPermissionsException("You do not have permission to manage messages in channel {$channel->id}."));
1407+
}
1408+
}
1409+
1410+
if (isset($this->attributes['webhook_id'])) {
1411+
if (! $webhook = $channel->webhooks->get('id', $this->attributes['webhook_id'])) {
1412+
return reject(new \Exception('Cannot find the webhook for this message (missing token).'));
1413+
}
1414+
1415+
return $webhook->messages->save($this, $reason);
1416+
}
1417+
1418+
/** @var Channel $channel */
1419+
return $channel->messages->save($this, $reason);
1420+
}
1421+
1422+
return parent::save();
1423+
}
1424+
13901425
/**
13911426
* @inheritDoc
13921427
*/

src/Discord/Parts/Channel/StageInstance.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,12 @@
1313

1414
namespace Discord\Parts\Channel;
1515

16+
use Discord\Http\Exceptions\NoPermissionsException;
1617
use Discord\Parts\Guild\Guild;
1718
use Discord\Parts\Part;
19+
use React\Promise\PromiseInterface;
20+
21+
use function React\Promise\reject;
1822

1923
/**
2024
* A Stage Instance holds information about a live stage.
@@ -120,6 +124,26 @@ public function getUpdatableAttributes(): array
120124
]);
121125
}
122126

127+
/**
128+
* @inheritDoc
129+
*/
130+
public function save(?string $reason = null): PromiseInterface
131+
{
132+
if (isset($this->attributes['channel_id'])) {
133+
/** @var Channel $channel */
134+
$channel = $this->channel ?? $this->factory->part(Channel::class, ['id' => $this->channel_id], true);
135+
if ($botperms = $channel->getBotPermissions()) {
136+
if ($botperms->manage_channels && $botperms->mute_members && $botperms->move_members) {
137+
return reject(new NoPermissionsException("You do not have permission to moderate members in the channel {$channel->id}."));
138+
}
139+
}
140+
141+
return $channel->stage_instances->save($this, $reason);
142+
}
143+
144+
return parent::save();
145+
}
146+
123147
/**
124148
* @inheritDoc
125149
*/

src/Discord/Parts/Channel/Webhook.php

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,9 @@
2424
use Symfony\Component\OptionsResolver\OptionsResolver;
2525

2626
/**
27-
* Webhooks are a low-effort way to post messages to channels in Discord. They
28-
* do not require a bot user or authentication to use.
27+
* Webhooks are a low-effort way to post messages to channels in Discord. They do not require a bot user or authentication to use.
28+
*
29+
* Apps can also subscribe to webhook events (i.e. outgoing webhooks) when events happen in Discord, which is detailed in the Webhook Events documentation.
2930
*
3031
* @link https://discord.com/developers/docs/resources/webhook#webhook-resource
3132
*
@@ -375,6 +376,16 @@ public function getUpdatableAttributes(): array
375376
]);
376377
}
377378

379+
/**
380+
* @inheritDoc
381+
*/
382+
public function save(?string $reason = null): PromiseInterface
383+
{
384+
$channel = $this->channel ?? $this->factory->part(Channel::class, ['id' => $this->channel_id], true);
385+
386+
return $channel->webhooks->save($this, $reason);
387+
}
388+
378389
/**
379390
* @inheritDoc
380391
*/

src/Discord/Parts/Guild/AutoModeration/Rule.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
use Discord\Parts\Guild\Role;
2121
use Discord\Parts\Part;
2222
use Discord\Parts\User\User;
23+
use React\Promise\PromiseInterface;
2324

2425
/**
2526
* Auto Moderation is a feature which allows each guild to set up rules that
@@ -229,6 +230,21 @@ public function getUpdatableAttributes(): array
229230
return $attr;
230231
}
231232

233+
/**
234+
* @inheritDoc
235+
*/
236+
public function save(?string $reason = null): PromiseInterface
237+
{
238+
if (isset($this->attributes['guild_id'])) {
239+
/** @var Guild $guild */
240+
$guild = $this->guild ?? $this->factory->part(Guild::class, ['id' => $this->attributes['guild_id']], true);
241+
242+
return $guild->autoModerationRules->save($this, $reason);
243+
}
244+
245+
return parent::save();
246+
}
247+
232248
/**
233249
* @inheritDoc
234250
*/

src/Discord/Parts/Guild/Ban.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@
1515

1616
use Discord\Parts\Part;
1717
use Discord\Parts\User\User;
18+
use React\Promise\PromiseInterface;
19+
20+
use function React\Promise\reject;
1821

1922
/**
2023
* A Ban is a ban on a user specific to a guild. It is also IP based.
@@ -88,6 +91,26 @@ protected function getUserAttribute(): User
8891
return $this->attributePartHelper('user', User::class);
8992
}
9093

94+
/**
95+
* @inheritDoc
96+
*/
97+
public function save(?string $reason = null): PromiseInterface
98+
{
99+
if (isset($this->attributes['guild_id'])) {
100+
/** @var Guild $guild */
101+
$guild = $this->guild ?? $this->factory->part(Guild::class, ['id' => $this->attributes['guild_id']], true);
102+
if ($botperms = $guild->getBotPermissions()) {
103+
if (! $botperms->ban_members) {
104+
return reject(new \DomainException("You do not have permission to ban members in the guild {$guild->id}."));
105+
}
106+
}
107+
108+
return $guild->bans->save($this, $reason);
109+
}
110+
111+
return parent::save();
112+
}
113+
91114
/**
92115
* @inheritDoc
93116
*/

0 commit comments

Comments
 (0)