diff --git a/src/Discord/Helpers/CollectionInterface.php b/src/Discord/Helpers/CollectionInterface.php index 679ae2d05..75e3dff7e 100644 --- a/src/Discord/Helpers/CollectionInterface.php +++ b/src/Discord/Helpers/CollectionInterface.php @@ -22,7 +22,8 @@ interface CollectionInterface extends ArrayAccess, JsonSerializable, IteratorAgg public function get(string $discrim, $key); public function set($offset, $value); public function pull($key, $default = null); - public function fill(array $items): self; + public function shift(); + public function fill($items): self; public function push(...$items): self; public function pushItem($item): self; public function count(): int; @@ -35,9 +36,17 @@ public function find(callable $callback); public function clear(): void; public function slice(int $offset, ?int $length, bool $preserve_keys = false); public function sort(callable|int|null $callback); + public function walk(callable $callback, mixed $arg); + public function reduce(callable $callback, $initial = null); public function map(callable $callback); public function merge($collection): self; public function toArray(); + public function collect(); + public function keys(): array; + public function values(): array; + public function diff($items, ?callable $callback); + public function intersect($items, ?callable $callback); + public function unique(int $flags = SORT_STRING); public function offsetExists($offset): bool; #[\ReturnTypeWillChange] public function offsetGet($offset); @@ -46,7 +55,7 @@ public function offsetUnset($offset): void; public function serialize(int $flags = 0, ?int $depth = 512): string; public function __serialize(): array; public function unserialize(string $serialized): void; - public function __unserialize(array $data): void; + public function __unserialize($data): void; public function jsonSerialize(): array; public function getIterator(): Traversable; public function __debugInfo(): array; diff --git a/src/Discord/Helpers/CollectionTrait.php b/src/Discord/Helpers/CollectionTrait.php index 2b70a4b0a..62566b577 100644 --- a/src/Discord/Helpers/CollectionTrait.php +++ b/src/Discord/Helpers/CollectionTrait.php @@ -18,7 +18,7 @@ trait CollectionTrait * * @param array $items * @param ?string $discrim - * @param string|null $class + * @param ?string $class */ public function __construct(array $items = [], ?string $discrim = 'id', ?string $class = null) { @@ -32,7 +32,7 @@ public function __construct(array $items = [], ?string $discrim = 'id', ?string * * @param array $items * @param ?string $discrim - * @param string|null $class + * @param ?string $class * * @return static */ @@ -113,15 +113,40 @@ public function pull($key, $default = null) return $default; } + /** + * Shifts an item from the collection. + * + * @return mixed + */ + public function shift() + { + if (empty($this->items)) { + return null; + } + + reset($this->items); + $key = key($this->items); + $value = array_shift($this->items); + + return [$key => $value]; + } + /** * Fills an array of items into the collection. * - * @param array $items + * @param CollectionInterface|array $items * * @return self */ - public function fill(array $items): self + public function fill($items): self { + if ($items instanceof CollectionInterface) { + $items = $items->toArray(); + } + if (! is_array($items)) { + throw new \InvalidArgumentException('The fill method only accepts arrays or CollectionInterface instances.'); + } + foreach ($items as $item) { $this->pushItem($item); } @@ -298,8 +323,8 @@ public function clear(): void /** * Slices the collection. * - * @param int $offset - * @param null|int $length + * @param int $offset + * @param ?int $length * @param bool $preserve_keys * * @return CollectionInterface @@ -331,6 +356,88 @@ public function sort(callable|int|null $callback) return new Collection($items, $this->discrim, $this->class); } + /** + * Gets the difference between the items. + * + * If a callback is provided and is callable, it uses `array_udiff_assoc` to compute the difference. + * Otherwise, it uses `array_diff`. + * + * @param CollectionInterface|array $array + * @param ?callable $callback + * + * @return CollectionInterface + */ + public function diff($items, ?callable $callback) + { + $items = $items instanceof CollectionInterface + ? $items->toArray() + : $items; + + $diff = $callback && is_callable($callback) + ? array_udiff_assoc($this->items, $items, $callback) + : array_diff($this->items, $items); + + return new Collection($diff, $this->discrim, $this->class); + } + + /** + * Gets the intersection of the items. + * + * If a callback is provided and is callable, it uses `array_uintersect_assoc` to compute the intersection. + * Otherwise, it uses `array_intersect`. + * + * @param CollectionInterface|array $array + * @param ?callable $callback + * + * @return CollectionInterface + */ + public function intersect($items, ?callable $callback) + { + $items = $items instanceof CollectionInterface + ? $items->toArray() + : $items; + + $diff = $callback && is_callable($callback) + ? array_uintersect_assoc($this->items, $items, $callback) + : array_intersect($this->items, $items); + + return new Collection($diff, $this->discrim, $this->class); + } + + /** + * Applies the given callback function to each item in the collection. + * + * @param callable $callback + * @param mixed $arg + * + * @return CollectionInterface + */ + public function walk(callable $callback, mixed $arg) + { + $items = $this->items; + + array_walk($items, $callback, $arg); + + return new Collection($items, $this->discrim, $this->class); + } + + /** + * Reduces the collection to a single value using a callback function. + * + * @param callable $callback + * @param ?mixed $initial + * + * @return CollectionInterface + */ + public function reduce(callable $callback, $initial = null) + { + $items = $this->items; + + $items = array_reduce($items, $callback, $initial); + + return new Collection($items, $this->discrim, $this->class); + } + /** * Runs a callback over the collection and creates a new static. * @@ -346,6 +453,18 @@ public function map(callable $callback) return new Collection(array_combine($keys, $values), $this->discrim, $this->class); } + /** + * Returns unique items. + * + * @param int $flags + * + * @return CollectionInterface + */ + public function unique(int $flags = SORT_STRING) + { + return new Collection(array_unique($this->items, $flags), $this->discrim, $this->class); + } + /** * Merges another collection into this collection. * @@ -355,7 +474,11 @@ public function map(callable $callback) */ public function merge($collection): self { - $this->items = array_merge($this->items, $collection->toArray()); + $items = $collection instanceof CollectionInterface + ? $collection->toArray() + : $collection; + + $this->items = array_merge($this->items, $items); return $this; } @@ -370,6 +493,16 @@ public function toArray() return $this->items; } + /** + * Converts the items into a new collection. + * + * @return CollectionInterface + */ + public function collect() + { + return new Collection($this->items, $this->discrim, $this->class); + } + /** * @since 11.0.0 * @@ -382,6 +515,16 @@ public function keys(): array return array_keys($this->items); } + /** + * Get the values of the items. + * + * @return array + */ + public function values(): array + { + return array_values($this->items); + } + /** * If the collection has an offset. * @@ -431,6 +574,9 @@ public function offsetUnset($offset): void /** * Returns the string representation of the collection. * + * @param int $flags + * @param ?int $depth + * * @return string */ public function serialize(int $flags = 0, ?int $depth = 512): string @@ -461,10 +607,17 @@ public function unserialize(string $serialized): void /** * Unserializes the collection. * - * @param array $data + * @param CollectionInterface|array $data */ - public function __unserialize(array $data): void + public function __unserialize($data): void { + if ($data instanceof CollectionInterface) { + $data = $data->toArray(); + } + if (! is_array($data)) { + throw new \InvalidArgumentException('The __unserialize method only accepts arrays or CollectionInterface instances.'); + } + $this->items = $data; } diff --git a/src/Discord/Parts/Channel/Channel.php b/src/Discord/Parts/Channel/Channel.php index 75deb273e..fd825057a 100644 --- a/src/Discord/Parts/Channel/Channel.php +++ b/src/Discord/Parts/Channel/Channel.php @@ -15,6 +15,7 @@ use Discord\Builders\MessageBuilder; use Discord\Exceptions\InvalidOverwriteException; use Discord\Helpers\Collection; +use Discord\Helpers\CollectionInterface; use Discord\Parts\Embed\Embed; use Discord\Parts\Guild\Guild; use Discord\Parts\Guild\Role; @@ -253,7 +254,7 @@ protected function getRecipientIdAttribute(): ?string * * @return Collection A collection of recipients. */ - protected function getRecipientsAttribute(): Collection + protected function getRecipientsAttribute(): CollectionInterface { $recipients = Collection::for(User::class); @@ -999,7 +1000,7 @@ protected function getPermissionOverwritesAttribute(): ?array * * @since 7.4.0 */ - protected function getAvailableTagsAttribute(): Collection + protected function getAvailableTagsAttribute(): CollectionInterface { $available_tags = Collection::for(Tag::class); diff --git a/src/Discord/Parts/Channel/Message.php b/src/Discord/Parts/Channel/Message.php index ebe1485c7..844ecace6 100644 --- a/src/Discord/Parts/Channel/Message.php +++ b/src/Discord/Parts/Channel/Message.php @@ -14,6 +14,7 @@ use Carbon\Carbon; use Discord\Builders\MessageBuilder; use Discord\Helpers\Collection; +use Discord\Helpers\CollectionInterface; use Discord\Parts\Channel\Poll; use Discord\Parts\Embed\Embed; use Discord\Parts\Guild\Emoji; @@ -336,7 +337,7 @@ protected function getSuppressNotificationsAttribute(): bool * * @return Collection|Channel[] */ - protected function getMentionChannelsAttribute(): Collection + protected function getMentionChannelsAttribute(): CollectionInterface { $collection = Collection::for(Channel::class); @@ -360,7 +361,7 @@ protected function getMentionChannelsAttribute(): Collection * * @return Collection|Attachment[] Attachment objects. */ - protected function getAttachmentsAttribute(): Collection + protected function getAttachmentsAttribute(): CollectionInterface { $attachments = Collection::for(Attachment::class); @@ -492,7 +493,7 @@ protected function getGuildAttribute(): ?Guild * * @return Collection The roles that were mentioned. null role only contains the ID in the collection. */ - protected function getMentionRolesAttribute(): Collection + protected function getMentionRolesAttribute(): CollectionInterface { $roles = new Collection(); @@ -516,7 +517,7 @@ protected function getMentionRolesAttribute(): Collection * * @return Collection|User[] The users that were mentioned. */ - protected function getMentionsAttribute(): Collection + protected function getMentionsAttribute(): CollectionInterface { $users = Collection::for(User::class); @@ -583,7 +584,7 @@ protected function getMemberAttribute(): ?Member * * @return Collection A collection of embeds. */ - protected function getEmbedsAttribute(): Collection + protected function getEmbedsAttribute(): CollectionInterface { $embeds = new Collection([], null); diff --git a/src/Discord/Parts/Embed/Embed.php b/src/Discord/Parts/Embed/Embed.php index 811635a39..8d0bc3c29 100644 --- a/src/Discord/Parts/Embed/Embed.php +++ b/src/Discord/Parts/Embed/Embed.php @@ -13,6 +13,7 @@ use Carbon\Carbon; use Discord\Helpers\Collection; +use Discord\Helpers\CollectionInterface; use Discord\Parts\Channel\Attachment; use Discord\Parts\Part; use function Discord\poly_strlen; @@ -137,7 +138,7 @@ protected function getAuthorAttribute(): Author * * @return Collection|Field[] */ - protected function getFieldsAttribute(): Collection + protected function getFieldsAttribute(): CollectionInterface { $fields = Collection::for(Field::class, null); diff --git a/src/Discord/Parts/Guild/AuditLog/AuditLog.php b/src/Discord/Parts/Guild/AuditLog/AuditLog.php index 1cba91e8a..13cf16be6 100644 --- a/src/Discord/Parts/Guild/AuditLog/AuditLog.php +++ b/src/Discord/Parts/Guild/AuditLog/AuditLog.php @@ -12,6 +12,7 @@ namespace Discord\Parts\Guild\AuditLog; use Discord\Helpers\Collection; +use Discord\Helpers\CollectionInterface; use Discord\Parts\Channel\Webhook; use Discord\Parts\Guild\AutoModeration\Rule; use Discord\Parts\Guild\Guild; @@ -76,7 +77,7 @@ protected function getGuildAttribute(): ?Guild * * @return Collection|Command[] */ - protected function getApplicationCommandsAttribute(): Collection + protected function getApplicationCommandsAttribute(): CollectionInterface { $collection = Collection::for(Command::class); @@ -92,7 +93,7 @@ protected function getApplicationCommandsAttribute(): Collection * * @return Collection|Entry[] */ - protected function getAuditLogEntriesAttribute(): Collection + protected function getAuditLogEntriesAttribute(): CollectionInterface { $collection = Collection::for(Entry::class); @@ -108,7 +109,7 @@ protected function getAuditLogEntriesAttribute(): Collection * * @return Collection|Rule[] */ - protected function getAutoModerationRulesAttribute(): Collection + protected function getAutoModerationRulesAttribute(): CollectionInterface { $collection = Collection::for(Rule::class); @@ -124,7 +125,7 @@ protected function getAutoModerationRulesAttribute(): Collection * * @return Collection|ScheduledEvent[] */ - protected function getGuildScheduledEventsAttribute(): Collection + protected function getGuildScheduledEventsAttribute(): CollectionInterface { $collection = Collection::for(ScheduledEvent::class); @@ -142,7 +143,7 @@ protected function getGuildScheduledEventsAttribute(): Collection * * @return Collection|Integration[] */ - protected function getIntegrationsAttribute(): Collection + protected function getIntegrationsAttribute(): CollectionInterface { $collection = Collection::for(Integration::class); @@ -158,7 +159,7 @@ protected function getIntegrationsAttribute(): Collection * * @return Collection|Thread[] */ - protected function getThreadsAttribute(): Collection + protected function getThreadsAttribute(): CollectionInterface { $collection = Collection::for(Thread::class); @@ -174,7 +175,7 @@ protected function getThreadsAttribute(): Collection * * @return Collection|User[] */ - protected function getUsersAttribute(): Collection + protected function getUsersAttribute(): CollectionInterface { $collection = Collection::for(User::class); @@ -190,7 +191,7 @@ protected function getUsersAttribute(): Collection * * @return Collection|Webhook[] */ - protected function getWebhooksAttribute(): Collection + protected function getWebhooksAttribute(): CollectionInterface { $collection = Collection::for(Webhook::class); @@ -210,7 +211,7 @@ protected function getWebhooksAttribute(): Collection * * @return Collection|Entry[] */ - public function searchByType(int $action_type): Collection + public function searchByType(int $action_type): CollectionInterface { $types = array_values((new ReflectionClass(Entry::class))->getConstants()); diff --git a/src/Discord/Parts/Guild/AuditLog/Entry.php b/src/Discord/Parts/Guild/AuditLog/Entry.php index 70ccc9979..6ef005381 100644 --- a/src/Discord/Parts/Guild/AuditLog/Entry.php +++ b/src/Discord/Parts/Guild/AuditLog/Entry.php @@ -12,6 +12,7 @@ namespace Discord\Parts\Guild\AuditLog; use Discord\Helpers\Collection; +use Discord\Helpers\CollectionInterface; use Discord\Parts\Part; use Discord\Parts\User\User; @@ -123,7 +124,7 @@ protected function getUserAttribute(): ?User * * @return Collection */ - protected function getChangesAttribute(): Collection + protected function getChangesAttribute(): CollectionInterface { return new Collection($this->attributes['changes'] ?? [], 'key', null); } diff --git a/src/Discord/Parts/Guild/AutoModeration/Rule.php b/src/Discord/Parts/Guild/AutoModeration/Rule.php index 935f3e277..0d983ff89 100644 --- a/src/Discord/Parts/Guild/AutoModeration/Rule.php +++ b/src/Discord/Parts/Guild/AutoModeration/Rule.php @@ -12,6 +12,7 @@ namespace Discord\Parts\Guild\AutoModeration; use Discord\Helpers\Collection; +use Discord\Helpers\CollectionInterface; use Discord\Parts\Channel\Channel; use Discord\Parts\Guild\Guild; use Discord\Parts\Guild\Role; @@ -100,7 +101,7 @@ protected function getCreatorAttribute(): ?User * * @return Collection|Action[] A collection of actions. */ - protected function getActionsAttribute(): Collection + protected function getActionsAttribute(): CollectionInterface { $actions = Collection::for(Action::class, null); @@ -116,7 +117,7 @@ protected function getActionsAttribute(): Collection * * @return Collection|?Role[] A collection of roles exempt from the rule. */ - protected function getExemptRolesAttribute(): Collection + protected function getExemptRolesAttribute(): CollectionInterface { $roles = new Collection(); @@ -140,7 +141,7 @@ protected function getExemptRolesAttribute(): Collection * * @return Collection|?Channel[] A collection of channels exempt from the rule. */ - protected function getExemptChannelsAttribute(): Collection + protected function getExemptChannelsAttribute(): CollectionInterface { $channels = new Collection(); diff --git a/src/Discord/Parts/Guild/CommandPermissions.php b/src/Discord/Parts/Guild/CommandPermissions.php index 7d297419b..eabeb716a 100644 --- a/src/Discord/Parts/Guild/CommandPermissions.php +++ b/src/Discord/Parts/Guild/CommandPermissions.php @@ -13,6 +13,7 @@ use Discord\Helpers\BigInt; use Discord\Helpers\Collection; +use Discord\Helpers\CollectionInterface; use Discord\Parts\Interactions\Command\Permission; use Discord\Parts\Part; @@ -57,7 +58,7 @@ protected function getGuildAttribute(): ?Guild * * @return Collection|Permission[] A collection of permissions. */ - protected function getPermissionsAttribute(): Collection + protected function getPermissionsAttribute(): CollectionInterface { $permissions = Collection::for(Permission::class); diff --git a/src/Discord/Parts/Guild/Emoji.php b/src/Discord/Parts/Guild/Emoji.php index b353ee11b..ef730660d 100644 --- a/src/Discord/Parts/Guild/Emoji.php +++ b/src/Discord/Parts/Guild/Emoji.php @@ -12,6 +12,7 @@ namespace Discord\Parts\Guild; use Discord\Helpers\Collection; +use Discord\Helpers\CollectionInterface; use Discord\Parts\Part; use Discord\Parts\User\User; use Stringable; @@ -69,7 +70,7 @@ protected function getGuildAttribute(): ?Guild * * @return Collection A collection of roles for the emoji. */ - protected function getRolesAttribute(): Collection + protected function getRolesAttribute(): CollectionInterface { $roles = new Collection(); diff --git a/src/Discord/Parts/Guild/Guild.php b/src/Discord/Parts/Guild/Guild.php index 215bd8a76..a6bb12e83 100644 --- a/src/Discord/Parts/Guild/Guild.php +++ b/src/Discord/Parts/Guild/Guild.php @@ -14,6 +14,7 @@ use Carbon\Carbon; use Discord\Exceptions\FileNotFoundException; use Discord\Helpers\Collection; +use Discord\Helpers\CollectionInterface; use Discord\Helpers\Multipart; use Discord\Http\Endpoint; use Discord\Http\Exceptions\NoPermissionsException; @@ -335,12 +336,22 @@ protected function setChannelsAttribute(?array $channels): void /** * Sets the roles attribute. * - * @param ?array $roles + * @param CollectionInterface|array|null $roles */ - protected function setRolesAttribute(?array $roles): void + protected function setRolesAttribute($roles): void { + if ($roles instanceof CollectionInterface) { + $roles = $roles->toArray(); + } + if ($roles === null) { + $roles = []; + } + if (! is_array($roles)) { + throw new \InvalidArgumentException('Roles must be an array or CollectionInterface.'); + } + $rolesDiscrim = $this->roles->discrim; - foreach ($roles ?? [] as $role) { + foreach ($roles as $role) { $role = (array) $role; /** @var ?Role */ if ($rolePart = $this->roles->offsetGet($role[$rolesDiscrim])) { @@ -570,7 +581,7 @@ protected function getSplashHashAttribute(): ?string * * @return Collection|StageInstance[] */ - protected function getStageInstancesAttribute(): Collection + protected function getStageInstancesAttribute(): CollectionInterface { $stage_instances = Collection::for(StageInstance::class); @@ -1106,16 +1117,23 @@ public function getBotPermissions(): ?RolePermission * * @link https://discord.com/developers/docs/resources/guild#modify-guild-role-positions * - * @param array $roles Associative array where the LHS key is the position, - * and the RHS value is a `Role` object or a string ID, - * e.g. `[1 => 'role_id_1', 3 => 'role_id_3']`. + * @param CollectionInterface|array $roles Associative array where the LHS key is the position, + * and the RHS value is a `Role` object or a string ID, + * e.g. `[1 => 'role_id_1', 3 => 'role_id_3']`. * * @throws NoPermissionsException Missing manage_roles permission. * * @return PromiseInterface */ - public function updateRolePositions(array $roles): PromiseInterface + public function updateRolePositions($roles): PromiseInterface { + if ($roles instanceof CollectionInterface) { + $roles = $roles->toArray(); + } + if (! is_array($roles)) { + return reject(new \InvalidArgumentException('Roles must be an array of Role instances or Role IDs.')); + } + $botperms = $this->getBotPermissions(); if ($botperms && ! $botperms->manage_roles) { return reject(new NoPermissionsException("You do not have permission to update role positions in the guild {$this->id}.")); diff --git a/src/Discord/Parts/Guild/WelcomeScreen.php b/src/Discord/Parts/Guild/WelcomeScreen.php index 3ea37c850..5168537c5 100644 --- a/src/Discord/Parts/Guild/WelcomeScreen.php +++ b/src/Discord/Parts/Guild/WelcomeScreen.php @@ -12,6 +12,7 @@ namespace Discord\Parts\Guild; use Discord\Helpers\Collection; +use Discord\Helpers\CollectionInterface; use Discord\Parts\Part; /** @@ -39,7 +40,7 @@ class WelcomeScreen extends Part * * @return Collection|WelcomeChannel[] The channels of welcome screen. */ - protected function getWelcomeChannelsAttribute(): Collection + protected function getWelcomeChannelsAttribute(): CollectionInterface { $collection = Collection::for(WelcomeChannel::class, null); diff --git a/src/Discord/Parts/Interactions/Command/Option.php b/src/Discord/Parts/Interactions/Command/Option.php index 6900ff6be..79539666f 100644 --- a/src/Discord/Parts/Interactions/Command/Option.php +++ b/src/Discord/Parts/Interactions/Command/Option.php @@ -12,6 +12,7 @@ namespace Discord\Parts\Interactions\Command; use Discord\Helpers\Collection; +use Discord\Helpers\CollectionInterface; use Discord\Parts\Part; use function Discord\poly_strlen; @@ -97,7 +98,7 @@ protected function getChoicesAttribute(): ?Collection * * @return Collection|Option[] A collection of options. */ - protected function getOptionsAttribute(): Collection + protected function getOptionsAttribute(): CollectionInterface { $options = Collection::for(Option::class, null); diff --git a/src/Discord/Parts/User/Member.php b/src/Discord/Parts/User/Member.php index cdf2088e7..bbc52dda7 100644 --- a/src/Discord/Parts/User/Member.php +++ b/src/Discord/Parts/User/Member.php @@ -15,6 +15,7 @@ use Discord\Builders\MessageBuilder; use Discord\Helpers\BigInt; use Discord\Helpers\Collection; +use Discord\Helpers\CollectionInterface; use Discord\Http\Endpoint; use Discord\Http\Exceptions\NoPermissionsException; use Discord\Parts\Channel\Channel; @@ -331,15 +332,22 @@ public function removeRole($role, ?string $reason = null): PromiseInterface * * @link https://discord.com/developers/docs/resources/guild#modify-guild-member * - * @param Role[]|string[] $roles The roles to set to the member. - * @param string|null $reason Reason for Audit Log. + * @param CollectionInterface|Role[]|string[] $roles The roles to set to the member. + * @param string|null $reason Reason for Audit Log. * * @throws NoPermissionsException Missing manage_roles permission. * * @return PromiseInterface */ - public function setRoles(array $roles, ?string $reason = null): PromiseInterface + public function setRoles($roles, ?string $reason = null): PromiseInterface { + if ($roles instanceof CollectionInterface) { + $roles = $roles->toArray(); + } + if (! is_array($roles)) { + return reject(new \InvalidArgumentException('Roles must be an array of Role instances or Role IDs.')); + } + foreach ($roles as $i => $role) { if ($role instanceof Role) { $roles[$i] = $role->id; @@ -611,7 +619,7 @@ protected function getGameAttribute(): ?Activity * * @return Collection|Activity[] */ - protected function getActivitiesAttribute(): Collection + protected function getActivitiesAttribute(): CollectionInterface { $activities = Collection::for(Activity::class, null); @@ -687,7 +695,7 @@ protected function getGuildAttribute(): ?Guild * * @return Collection A collection of roles the member is in. null role only contains ID in the collection. */ - protected function getRolesAttribute(): Collection + protected function getRolesAttribute(): CollectionInterface { $roles = new Collection(); diff --git a/src/Discord/Parts/WebSockets/PresenceUpdate.php b/src/Discord/Parts/WebSockets/PresenceUpdate.php index 911e9306b..f7133d956 100644 --- a/src/Discord/Parts/WebSockets/PresenceUpdate.php +++ b/src/Discord/Parts/WebSockets/PresenceUpdate.php @@ -12,6 +12,7 @@ namespace Discord\Parts\WebSockets; use Discord\Helpers\Collection; +use Discord\Helpers\CollectionInterface; use Discord\Parts\Guild\Guild; use Discord\Parts\Guild\Role; use Discord\Parts\Part; @@ -95,7 +96,7 @@ protected function getGuildAttribute(): ?Guild * * @return Collection|Activity[] */ - protected function getActivitiesAttribute(): Collection + protected function getActivitiesAttribute(): CollectionInterface { $collection = Collection::for(Activity::class, null); @@ -165,7 +166,7 @@ protected function getMemberAttribute(): ?Member * * @return Collection|Role[] */ - protected function getRolesAttribute(): Collection + protected function getRolesAttribute(): CollectionInterface { if ($member = $this->member) { return $member->roles; diff --git a/src/Discord/Repository/AbstractRepositoryInterface.php b/src/Discord/Repository/AbstractRepositoryInterface.php index edb6bf5eb..15bf94176 100644 --- a/src/Discord/Repository/AbstractRepositoryInterface.php +++ b/src/Discord/Repository/AbstractRepositoryInterface.php @@ -40,6 +40,7 @@ public function find(callable $callback); public function clear(): void; public function toArray(): array; public function keys(): array; + public function values(): array; public function offsetExists($offset): bool; #[\ReturnTypeWillChange] public function offsetGet($offset); diff --git a/src/Discord/Repository/AbstractRepositoryTrait.php b/src/Discord/Repository/AbstractRepositoryTrait.php index 2b4188fea..2ed029ee3 100644 --- a/src/Discord/Repository/AbstractRepositoryTrait.php +++ b/src/Discord/Repository/AbstractRepositoryTrait.php @@ -669,6 +669,16 @@ public function keys(): array return array_keys($this->items); } + /** + * Get the values of the items. + * + * @return array + */ + public function values(): array + { + return array_values($this->items); + } + /** * If the repository has an offset. * diff --git a/src/Discord/Repository/Channel/ThreadRepository.php b/src/Discord/Repository/Channel/ThreadRepository.php index e4dabada2..c700e1481 100644 --- a/src/Discord/Repository/Channel/ThreadRepository.php +++ b/src/Discord/Repository/Channel/ThreadRepository.php @@ -12,6 +12,7 @@ namespace Discord\Repository\Channel; use Discord\Helpers\Collection; +use Discord\Helpers\CollectionInterface; use Discord\Http\Endpoint; use Discord\Parts\Thread\Thread; use Discord\Repository\AbstractRepository; @@ -152,7 +153,7 @@ public function archived(bool $private = false, bool $joined = false, ?int $limi * * @return Collection|Thread[] */ - private function handleThreadPaginationResponse(object $response): Collection + private function handleThreadPaginationResponse(object $response): CollectionInterface { $collection = Collection::for(Thread::class);