-
Notifications
You must be signed in to change notification settings - Fork 23
fix(voice-channel): improve channel deletion and state handling logic #212
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -4,18 +4,21 @@ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| namespace He4rt\BotDiscord\Actions\VoiceChannel; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| use He4rt\BotDiscord\DTO\VoiceChannelDTO; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| final class HandleStateChannelAction | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| public function execute(int|string $userId, ?string $channelId): void | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| $activeChannels = cache()->tags(['voice_channels'])->get('active_voice_channels_keys', []); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| $activeChannels = $this->loadChannels(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| $oldChannelId = $this->getUserLastChannel($userId); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if ($this->isLeavingVoice($channelId, $oldChannelId)) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| resolve(LeftChannelAction::class)->execute( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| activeChannels: $activeChannels, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| user: $userId | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| $this->saveChannels($activeChannels); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| $this->clearUserLastChannel($userId); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -33,6 +36,7 @@ public function execute(int|string $userId, ?string $channelId): void | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| activeChannels: $activeChannels, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| user: $userId | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| $this->saveChannels($activeChannels); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| $this->setUserLastChannel($userId, $channelId); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -45,6 +49,7 @@ public function execute(int|string $userId, ?string $channelId): void | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| activeChannels: $activeChannels, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| user: $userId | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| $this->saveChannels($activeChannels); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| $this->setUserLastChannel($userId, $channelId); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -94,4 +99,41 @@ private function isUpdatingInSameChannel(?string $newChannelId, ?string $oldChan | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return !is_null($newChannelId) && $oldChannelId === $newChannelId; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * @return array<VoiceChannelDTO> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private function loadChannels(): array | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| $channels = cache()->tags(['voice_channels'])->get('active_voice_channels_keys', []); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return array_map(function ($channel): ?VoiceChannelDTO { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if ($channel instanceof VoiceChannelDTO) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return $channel; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (is_array($channel) && isset($channel['guildId'], $channel['channelId'], $channel['ownerId'])) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return VoiceChannelDTO::make($channel); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return null; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, $channels); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+103
to
+121
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Two robustness gaps:
Both can be addressed by reusing the same normalization and filtering nulls. 🛡️ Proposed fix /**
* `@return` array<VoiceChannelDTO>
*/
private function loadChannels(): array
{
$channels = cache()->tags(['voice_channels'])->get('active_voice_channels_keys', []);
- return array_map(function ($channel): ?VoiceChannelDTO {
+ $mapped = array_map(function ($channel): ?VoiceChannelDTO {
if ($channel instanceof VoiceChannelDTO) {
return $channel;
}
- if (is_array($channel) && isset($channel['guildId'], $channel['channelId'], $channel['ownerId'])) {
- return VoiceChannelDTO::make($channel);
+ $data = match (true) {
+ is_array($channel) => $channel,
+ $channel instanceof \stdClass => (array) $channel,
+ default => null,
+ };
+
+ if ($data !== null && isset($data['guildId'], $data['channelId'], $data['ownerId'])) {
+ return VoiceChannelDTO::make($data);
}
return null;
}, $channels);
+
+ return array_values(array_filter($mapped));
}📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * @param array<VoiceChannelDTO> $channels | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private function saveChannels(array $channels): void | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| $arrays = array_map(fn (VoiceChannelDTO $dto) => [ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 'guildId' => $dto->guildId, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 'channelId' => $dto->channelId, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 'ownerId' => $dto->ownerId, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 'usersCount' => $dto->usersCount, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 'users' => $dto->users, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 'lastJoinedAt' => $dto->lastJoinedAt?->toIso8601String(), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ], $channels); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| cache()->tags(['voice_channels'])->put('active_voice_channels_keys', $arrays); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -5,6 +5,7 @@ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| namespace He4rt\BotDiscord\DTO; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| use Carbon\CarbonInterface; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| use Illuminate\Support\Facades\Date; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| final class VoiceChannelDTO | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -23,13 +24,22 @@ public function __construct( | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| public static function make(array $data): self | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| $lastJoinedAt = null; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (filled($data['lastJoinedAt'])) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if ($data['lastJoinedAt'] instanceof CarbonInterface) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| $lastJoinedAt = $data['lastJoinedAt']; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } elseif (is_string($data['lastJoinedAt'])) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| $lastJoinedAt = Date::parse($data['lastJoinedAt']); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+27
to
+34
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Guard against undefined CI is failing with 🐛 Proposed fix- $lastJoinedAt = null;
- if (filled($data['lastJoinedAt'])) {
- if ($data['lastJoinedAt'] instanceof CarbonInterface) {
- $lastJoinedAt = $data['lastJoinedAt'];
- } elseif (is_string($data['lastJoinedAt'])) {
- $lastJoinedAt = Date::parse($data['lastJoinedAt']);
- }
- }
+ $lastJoinedAt = null;
+ $rawLastJoinedAt = $data['lastJoinedAt'] ?? null;
+ if (filled($rawLastJoinedAt)) {
+ if ($rawLastJoinedAt instanceof CarbonInterface) {
+ $lastJoinedAt = $rawLastJoinedAt;
+ } elseif (is_string($rawLastJoinedAt)) {
+ $lastJoinedAt = Date::parse($rawLastJoinedAt);
+ }
+ }📝 Committable suggestion
Suggested change
🧰 Tools🪛 GitHub Actions: Continuous Integration[error] 28-28: Undefined array key "lastJoinedAt" in VoiceChannelDTO::make(). 🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return new self( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| guildId: $data['guildId'], | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| channelId: $data['channelId'], | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ownerId: $data['ownerId'], | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| usersCount: $data['usersCount'], | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| users: $data['users'], | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| lastJoinedAt: $data['lastJoinedAt'] ?? null, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| lastJoinedAt: $lastJoinedAt, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
25
to
44
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win Consider centralizing DTO ↔ array conversion here. The reverse mapping (DTO → array) is now duplicated in three places: ♻️ Proposed addition public function isLongTermEmpty(): bool
{
return abs(now()->diffInSeconds($this->lastJoinedAt)) >= 20;
}
+
+ /**
+ * `@return` array<string, mixed>
+ */
+ public function toArray(): array
+ {
+ return [
+ 'guildId' => $this->guildId,
+ 'channelId' => $this->channelId,
+ 'ownerId' => $this->ownerId,
+ 'usersCount' => $this->usersCount,
+ 'users' => $this->users,
+ 'lastJoinedAt' => $this->lastJoinedAt?->toIso8601String(),
+ ];
+ }
}📝 Committable suggestion
Suggested change
🧰 Tools🪛 GitHub Actions: Continuous Integration[error] 28-28: Undefined array key "lastJoinedAt" in VoiceChannelDTO::make(). 🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -81,7 +81,7 @@ | |||||||||||||||||||||||||||||||||||||||||||||||||||
| 'users' => [], | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| 'lastJoinedAt' => now(), | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| ]); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| $channels[] = $channelDto; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| $channels[] = $this->dtoToArray($channelDto); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| cache()->tags(['voice_channels'])->put('active_voice_channels_keys', $channels); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -149,4 +149,16 @@ | |||||||||||||||||||||||||||||||||||||||||||||||||||
| ->content(sprintf('Sala Criada com sucesso !! <#%s>', $channel->id)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| ->reply($interaction, true); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| private function dtoToArray(VoiceChannelDTO $dto): array | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Check failure on line 153 in app-modules/bot-discord/src/SlashCommands/DynamicVoiceCommand.php
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| return [ | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| 'guildId' => $dto->guildId, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| 'channelId' => $dto->channelId, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| 'ownerId' => $dto->ownerId, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| 'usersCount' => $dto->usersCount, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| 'users' => $dto->users, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| 'lastJoinedAt' => $dto->lastJoinedAt?->toIso8601String(), | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| ]; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+153
to
+163
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add PHPStan is failing on this method because the array shape is unspecified. Beyond that, this duplicates the same conversion present in 🛠️ Minimal fix for PHPStan- private function dtoToArray(VoiceChannelDTO $dto): array
+ /**
+ * `@return` array<string, mixed>
+ */
+ private function dtoToArray(VoiceChannelDTO $dto): array
{
return [
'guildId' => $dto->guildId,
'channelId' => $dto->channelId,
'ownerId' => $dto->ownerId,
'usersCount' => $dto->usersCount,
'users' => $dto->users,
'lastJoinedAt' => $dto->lastJoinedAt?->toIso8601String(),
];
}Preferred: replace the call at line 84 with 📝 Committable suggestion
Suggested change
🧰 Tools🪛 GitHub Check: Perform Phpstan Check / Run[failure] 153-153: 🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cache write can resurrect just-deleted channels.
When
$hasInvalidis true and at least one channel passes theisEmpty() && isLongTermEmpty()check:delete()(line 32) reads the cache, filters out that channel, and writes back the filtered list.$validChannels— which was populated before the delete and still contains the deleted channel — overwriting step 1.So channels that should have been removed will reappear in
active_voice_channels_keys. The fix is to perform a single, post-loop write with the final desired state, and drop the cache mutation insidedelete().🐛 Proposed fix (single cache write, delete() only handles Discord)
public function execute(Discord $discord): void { $channels = cache()->tags(['voice_channels'])->get('active_voice_channels_keys', []); - $validChannels = []; - $hasInvalid = false; + $remainingChannels = []; + $mutated = false; foreach ($channels as $channel) { $dto = $this->normalizeChannel($channel); if (!$dto instanceof VoiceChannelDTO) { - $hasInvalid = true; - + $mutated = true; continue; } - $validChannels[] = $dto; - if ($dto->isEmpty() && $dto->isLongTermEmpty()) { $this->delete($dto->guildId, $dto->channelId, $discord); + $mutated = true; + continue; } + + $remainingChannels[] = $dto; } - if ($hasInvalid) { - cache()->tags(['voice_channels'])->put('active_voice_channels_keys', $this->dtosToArrays($validChannels)); + if ($mutated) { + cache()->tags(['voice_channels'])->put('active_voice_channels_keys', $this->dtosToArrays($remainingChannels)); } }…and have
delete()only remove the Discord channel (drop its own cache read/write).🤖 Prompt for AI Agents