diff --git a/src/Discord/Builders/CommandAttributes.php b/src/Discord/Builders/CommandAttributes.php index 877dca08f..fd33d17b4 100644 --- a/src/Discord/Builders/CommandAttributes.php +++ b/src/Discord/Builders/CommandAttributes.php @@ -29,7 +29,7 @@ * @property ?string[]|null $name_localizations Localization dictionary for the name field. Values follow the same restrictions as name. * @property ?string $description 1-100 character description for CHAT_INPUT commands, empty string for USER and MESSAGE commands. * @property ?string[]|null $description_localizations Localization dictionary for the description field. Values follow the same restrictions as description. - * @property \Discord\Helpers\Collection|Option[]|null $options The parameters for the command, max 25. Only for Slash command (CHAT_INPUT). + * @property \Discord\Helpers\CollectionInterface|Option[]|null $options The parameters for the command, max 25. Only for Slash command (CHAT_INPUT). * @property ?string $default_member_permissions Set of permissions represented as a bit set. * @property bool|null $dm_permission Indicates whether the command is available in DMs with the app, only for globally-scoped commands. By default, commands are visible. * @property ?bool $default_permission Whether the command is enabled by default when the app is added to a guild. SOON DEPRECATED. diff --git a/src/Discord/Builders/Components/SelectMenu.php b/src/Discord/Builders/Components/SelectMenu.php index 54cb29098..70289930e 100644 --- a/src/Discord/Builders/Components/SelectMenu.php +++ b/src/Discord/Builders/Components/SelectMenu.php @@ -12,7 +12,7 @@ namespace Discord\Builders\Components; use Discord\Discord; -use Discord\Helpers\Collection; +use Discord\Helpers\CollectionInterface; use Discord\Parts\Interactions\Interaction; use Discord\WebSockets\Event; use React\Promise\PromiseInterface; @@ -350,7 +350,7 @@ public function setListener(?callable $callback, Discord $discord, bool $oneOff if (empty($this->options)) { $response = $callback($interaction); } else { - $options = Collection::for(Option::class, null); + $options = ($this->discord->getCollectionClass())::for(Option::class, null); foreach ($this->options as $option) { if (in_array($option->getValue(), $interaction->data->values)) { diff --git a/src/Discord/Discord.php b/src/Discord/Discord.php index 6a1c3a79e..601333fb6 100644 --- a/src/Discord/Discord.php +++ b/src/Discord/Discord.php @@ -15,6 +15,8 @@ use Discord\Factory\Factory; use Discord\Helpers\BigInt; use Discord\Helpers\CacheConfig; +use Discord\Helpers\Collection; +use Discord\Helpers\CollectionInterface; use Discord\Helpers\RegisteredCommand; use Discord\Http\Drivers\React; use Discord\Http\Endpoint; @@ -330,6 +332,13 @@ class Discord */ protected $cacheConfig; + /** + * The collection class. + * + * @var string + */ + protected $collectionClass; + /** * The Client class. * @@ -374,6 +383,10 @@ public function __construct(array $options = []) if ($cacheConfig = $this->getCacheConfig()) { $this->logger->warning('Attached experimental CacheInterface: '.get_class($cacheConfig->interface)); } + $this->collectionClass = $options['collection']; + if ($this->collectionClass !== Collection::class) { + $this->logger->warning("Attached experimental CollectionClass: {$this->collectionClass}"); + } $connector = new SocketConnector($options['socket_options'], $this->loop); $this->wsFactory = new Connector($this->loop, $connector); @@ -1408,6 +1421,7 @@ protected function resolveOptions(array $options = []): array 'socket_options', 'dnsConfig', 'cache', + 'collection', ]) ->setDefaults([ 'logger' => null, @@ -1418,6 +1432,7 @@ protected function resolveOptions(array $options = []): array 'intents' => Intents::getDefaultIntents(), 'socket_options' => [], 'cache' => [AbstractRepository::class => null], // use LegacyCacheWrapper + 'collection' => Collection::class, ]) ->setAllowedTypes('token', 'string') ->setAllowedTypes('logger', ['null', LoggerInterface::class]) @@ -1430,17 +1445,9 @@ protected function resolveOptions(array $options = []): array ->setAllowedTypes('socket_options', 'array') ->setAllowedTypes('dnsConfig', ['string', \React\Dns\Config\Config::class]) ->setAllowedTypes('cache', ['array', CacheConfig::class, \React\Cache\CacheInterface::class, \Psr\SimpleCache\CacheInterface::class]) - ->setNormalizer('cache', function ($options, $value) { - if (! is_array($value)) { - if (! ($value instanceof CacheConfig)) { - $value = new CacheConfig($value); - } - - return [AbstractRepository::class => $value]; - } - - return $value; - }); + ->setNormalizer('cache', fn($options, $value) => is_array($value) ? $value : [AbstractRepository::class => $value instanceof CacheConfig ? $value : new CacheConfig($value)]) + ->setAllowedTypes('collection', ['string', 'null']) + ->setAllowedValues('collection', fn($value) => $value === null || (class_exists($value) && isset(class_implements($value)[CollectionInterface::class]))); $options = $resolver->resolve($options); @@ -1614,6 +1621,18 @@ public function getCacheConfig($repository_class = AbstractRepository::class) return $this->cacheConfig[$repository_class]; } + /** + * Gets the collection configuration. + * + * @param string $collection_class Collection class name. + * + * @return string The class name of the collection, which implements CollectionInterface + */ + public function getCollectionClass() + { + return $this->collectionClass; + } + /** * Handles dynamic get calls to the client. * diff --git a/src/Discord/Helpers/RegisteredCommand.php b/src/Discord/Helpers/RegisteredCommand.php index 2378addfd..3207d9f10 100644 --- a/src/Discord/Helpers/RegisteredCommand.php +++ b/src/Discord/Helpers/RegisteredCommand.php @@ -90,7 +90,7 @@ public function __construct(Discord $discord, string $name, ?callable $callback */ public function execute(array $options, Interaction $interaction): bool { - $params = Collection::for(Option::class, 'name'); + $params = ($this->discord->getCollectionClass())::for(Option::class, 'name'); foreach ($options as $option) { if (isset($this->subCommands[$option->name])) { diff --git a/src/Discord/Parts/Channel/Channel.php b/src/Discord/Parts/Channel/Channel.php index 507db9a41..4e6792b03 100644 --- a/src/Discord/Parts/Channel/Channel.php +++ b/src/Discord/Parts/Channel/Channel.php @@ -14,7 +14,7 @@ use Carbon\Carbon; 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; @@ -70,7 +70,7 @@ * @property int|null $bitrate The bitrate of the channel. Only for voice channels. * @property int|null $user_limit The user limit of the channel. Max 99 for voice channels and 10000 for stage channels (0 refers to no limit). * @property int|null $rate_limit_per_user Amount of seconds a user has to wait before sending a new message (slow mode). - * @property Collection|User[] $recipients A collection of all the recipients in the channel. Only for DM or group channels. + * @property CollectionInterface|User[] $recipients A collection of all the recipients in the channel. Only for DM or group channels. * @property-read User|null $recipient The first recipient of the channel. Only for DM or group channels. * @property-read string|null $recipient_id The ID of the recipient of the channel, if it is a DM channel. * @property ?string|null $icon Icon hash. @@ -84,7 +84,7 @@ * @property int|null $default_auto_archive_duration Default duration for newly created threads, in minutes, to automatically archive the thread after recent activity, can be set to: 60, 1440, 4320, 10080. * @property string|null $permissions Computed permissions for the invoking user in the channel, including overwrites, only included when part of the resolved data received on an application command interaction. * @property int|null $flags Channel flags combined as a bitfield. - * @property Collection|Tag[] $available_tags Set of tags that can be used in a forum channel, limited to 20. + * @property CollectionInterface|Tag[] $available_tags Set of tags that can be used in a forum channel, limited to 20. * @property ?Reaction|null $default_reaction_emoji Emoji to show in the add reaction button on a thread in a forum channel. * @property int|null $default_thread_rate_limit_per_user The initial rate_limit_per_user to set on newly created threads in a forum channel. this field is copied to the thread at creation time and does not live update. * @property ?int|null $default_sort_order The default sort order type used to order posts in forum channels. @@ -251,11 +251,11 @@ protected function getRecipientIdAttribute(): ?string /** * Gets the recipients attribute. * - * @return Collection A collection of recipients. + * @return CollectionInterface A collection of recipients. */ - protected function getRecipientsAttribute(): Collection + protected function getRecipientsAttribute(): CollectionInterface { - $recipients = Collection::for(User::class); + $recipients = ($this->discord->getCollectionClass())::for(User::class); foreach ($this->attributes['recipients'] ?? [] as $recipient) { $recipients->pushItem($this->discord->users->get('id', $recipient->id) ?: $this->factory->part(User::class, (array) $recipient, true)); @@ -295,13 +295,13 @@ protected function getLastPinTimestampAttribute(): ?Carbon * * @link https://discord.com/developers/docs/resources/channel#get-pinned-messages * - * @return PromiseInterface> + * @return PromiseInterface> */ public function getPinnedMessages(): PromiseInterface { return $this->http->get(Endpoint::bind(Endpoint::CHANNEL_PINS, $this->id)) ->then(function ($responses) { - $messages = Collection::for(Message::class); + $messages = ($this->discord->getCollectionClass())::for(Message::class); foreach ($responses as $response) { $messages->pushItem($this->messages->get('id', $response->id) ?: $this->messages->create($response, true)); @@ -736,7 +736,7 @@ public function limitDelete(int $value, ?string $reason = null): PromiseInterfac * Or also missing `connect` permission for text in voice. * @throws \RangeException * - * @return PromiseInterface> + * @return PromiseInterface> * @todo Make it in a trait along with Thread */ public function getMessageHistory(array $options = []): PromiseInterface @@ -781,7 +781,7 @@ public function getMessageHistory(array $options = []): PromiseInterface } return $this->http->get($endpoint)->then(function ($responses) { - $messages = Collection::for(Message::class); + $messages = ($this->discord->getCollectionClass())::for(Message::class); foreach ($responses as $response) { $messages->pushItem($this->messages->get('id', $response->id) ?: $this->messages->create($response, true)); @@ -925,13 +925,13 @@ protected function getPermissionOverwritesAttribute(): ?array /** * Gets the available tags attribute. * - * @return Collection|Tag[] Available forum tags. + * @return CollectionInterface|Tag[] Available forum tags. * * @since 7.4.0 */ - protected function getAvailableTagsAttribute(): Collection + protected function getAvailableTagsAttribute(): CollectionInterface { - $available_tags = Collection::for(Tag::class); + $available_tags = ($this->discord->getCollectionClass())::for(Tag::class); foreach ($this->attributes['available_tags'] ?? [] as $available_tag) { $available_tags->pushItem($this->createOf(Tag::class, $available_tag)); @@ -1267,12 +1267,13 @@ public function broadcastTyping(): PromiseInterface * @param int $options['time'] Time in milliseconds until the collector finishes or false. * @param int $options['limit'] The amount of messages allowed or false. * - * @return PromiseInterface> + * @return PromiseInterface> */ public function createMessageCollector(callable $filter, array $options = []): PromiseInterface { $deferred = new Deferred(); - $messages = new Collection([], null, null); + /** @var CollectionInterface $messages An instance of the collection class implementing CollectionInterface.*/ + $messages = new ($this->discord->getCollectionClass())([], null, null); $timer = null; $options = array_merge([ diff --git a/src/Discord/Parts/Channel/Message.php b/src/Discord/Parts/Channel/Message.php index ebe1485c7..a0883e0eb 100644 --- a/src/Discord/Parts/Channel/Message.php +++ b/src/Discord/Parts/Channel/Message.php @@ -13,7 +13,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; @@ -45,39 +45,39 @@ * * @since 2.0.0 * - * @property string $id The unique identifier of the message. - * @property string $channel_id The unique identifier of the channel that the message was sent in. - * @property-read Channel|Thread $channel The channel that the message was sent in. - * @property User|null $author The author of the message. Will be a webhook if sent from one. - * @property-read string|null $user_id The user id of the author. - * @property string $content The content of the message if it is a normal message. - * @property Carbon $timestamp A timestamp of when the message was sent. - * @property Carbon|null $edited_timestamp A timestamp of when the message was edited, or null. - * @property bool $tts Whether the message was sent as a text-to-speech message. - * @property bool $mention_everyone Whether the message contained an @everyone mention. - * @property Collection|User[] $mentions A collection of the users mentioned in the message. - * @property Collection|Role[] $mention_roles A collection of roles that were mentioned in the message. - * @property Collection|Channel[] $mention_channels Collection of mentioned channels. - * @property Collection|Attachment[] $attachments Collection of attachment objects. - * @property Collection|Embed[] $embeds A collection of embed objects. - * @property ReactionRepository $reactions Collection of reactions on the message. - * @property string|null $nonce A randomly generated string that provides verification for the client. Not required. - * @property bool $pinned Whether the message is pinned to the channel. - * @property string|null $webhook_id ID of the webhook that made the message, if any. - * @property int $type The type of message. - * @property object|null $activity Current message activity. Requires rich presence. - * @property object|null $application Application of message. Requires rich presence. - * @property string|null $application_id If the message is a response to an Interaction, this is the id of the interaction's application. - * @property object|null $message_reference Message that is referenced by this message. - * @property int|null $flags Message flags. - * @property Message|null $referenced_message The message that is referenced in a reply. - * @property MessageInteraction|null $interaction Sent if the message is a response to an Interaction. - * @property Thread|null $thread The thread that was started from this message, includes thread member object. - * @property Collection|Component[]|null $components Sent if the message contains components like buttons, action rows, or other interactive components. - * @property Collection|Sticker[]|null $sticker_items Stickers attached to the message. - * @property int|null $position A generally increasing integer (there may be gaps or duplicates) that represents the approximate position of the message in a thread, it can be used to estimate the relative position of the message in a thread in company with `total_message_sent` on parent thread. - * @property object|null $role_subscription_data Data of the role subscription purchase or renewal that prompted this `ROLE_SUBSCRIPTION_PURCHASE` message. - * @property Poll|null $poll The poll attached to the message. + * @property string $id The unique identifier of the message. + * @property string $channel_id The unique identifier of the channel that the message was sent in. + * @property-read Channel|Thread $channel The channel that the message was sent in. + * @property User|null $author The author of the message. Will be a webhook if sent from one. + * @property-read string|null $user_id The user id of the author. + * @property string $content The content of the message if it is a normal message. + * @property Carbon $timestamp A timestamp of when the message was sent. + * @property Carbon|null $edited_timestamp A timestamp of when the message was edited, or null. + * @property bool $tts Whether the message was sent as a text-to-speech message. + * @property bool $mention_everyone Whether the message contained an @everyone mention. + * @property CollectionInterface|User[] $mentions A collection of the users mentioned in the message. + * @property CollectionInterface|Role[] $mention_roles A collection of roles that were mentioned in the message. + * @property CollectionInterface|Channel[] $mention_channels Collection of mentioned channels. + * @property CollectionInterface|Attachment[] $attachments Collection of attachment objects. + * @property CollectionInterface|Embed[] $embeds A collection of embed objects. + * @property ReactionRepository $reactions Collection of reactions on the message. + * @property string|null $nonce A randomly generated string that provides verification for the client. Not required. + * @property bool $pinned Whether the message is pinned to the channel. + * @property string|null $webhook_id ID of the webhook that made the message, if any. + * @property int $type The type of message. + * @property object|null $activity Current message activity. Requires rich presence. + * @property object|null $application Application of message. Requires rich presence. + * @property string|null $application_id If the message is a response to an Interaction, this is the id of the interaction's application. + * @property object|null $message_reference Message that is referenced by this message. + * @property int|null $flags Message flags. + * @property Message|null $referenced_message The message that is referenced in a reply. + * @property MessageInteraction|null $interaction Sent if the message is a response to an Interaction. + * @property Thread|null $thread The thread that was started from this message, includes thread member object. + * @property CollectionInterface|Component[]|null $components Sent if the message contains components like buttons, action rows, or other interactive components. + * @property CollectionInterface|Sticker[]|null $sticker_items Stickers attached to the message. + * @property int|null $position A generally increasing integer (there may be gaps or duplicates) that represents the approximate position of the message in a thread, it can be used to estimate the relative position of the message in a thread in company with `total_message_sent` on parent thread. + * @property object|null $role_subscription_data Data of the role subscription purchase or renewal that prompted this `ROLE_SUBSCRIPTION_PURCHASE` message. + * @property Poll|null $poll The poll attached to the message. * * @property-read bool $crossposted Message has been crossposted. * @property-read bool $is_crosspost Message is a crosspost from another channel. @@ -334,11 +334,11 @@ protected function getSuppressNotificationsAttribute(): bool /** * Gets the mention_channels attribute. * - * @return Collection|Channel[] + * @return CollectionInterface|Channel[] */ - protected function getMentionChannelsAttribute(): Collection + protected function getMentionChannelsAttribute(): CollectionInterface { - $collection = Collection::for(Channel::class); + $collection = ($this->discord->getCollectionClass())::for(Channel::class); if (preg_match_all('/<#([0-9]*)>/', $this->content, $matches)) { foreach ($matches[1] as $channelId) { @@ -358,11 +358,11 @@ protected function getMentionChannelsAttribute(): Collection /** * Returns any attached files. * - * @return Collection|Attachment[] Attachment objects. + * @return CollectionInterface|Attachment[] Attachment objects. */ - protected function getAttachmentsAttribute(): Collection + protected function getAttachmentsAttribute(): CollectionInterface { - $attachments = Collection::for(Attachment::class); + $attachments = ($this->discord->getCollectionClass())::for(Attachment::class); foreach ($this->attributes['attachments'] ?? [] as $attachment) { $attachments->pushItem($this->createOf(Attachment::class, $attachment)); @@ -490,11 +490,12 @@ protected function getGuildAttribute(): ?Guild /** * Returns the mention_roles attribute. * - * @return Collection The roles that were mentioned. null role only contains the ID in the collection. + * @return CollectionInterface 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(); + /** @var CollectionInterface $roles An instance of the collection class implementing CollectionInterface.*/ + $roles = new ($this->discord->getCollectionClass())(); if (empty($this->attributes['mention_roles'])) { return $roles; @@ -514,11 +515,11 @@ protected function getMentionRolesAttribute(): Collection /** * Returns the mention attribute. * - * @return Collection|User[] The users that were mentioned. + * @return CollectionInterface|User[] The users that were mentioned. */ - protected function getMentionsAttribute(): Collection + protected function getMentionsAttribute(): CollectionInterface { - $users = Collection::for(User::class); + $users = ($this->discord->getCollectionClass())::for(User::class); foreach ($this->attributes['mentions'] ?? [] as $mention) { $users->pushItem($this->discord->users->get('id', $mention->id) ?: $this->factory->part(User::class, (array) $mention, true)); @@ -581,11 +582,12 @@ protected function getMemberAttribute(): ?Member /** * Returns the embed attribute. * - * @return Collection A collection of embeds. + * @return CollectionInterface A collection of embeds. */ - protected function getEmbedsAttribute(): Collection + protected function getEmbedsAttribute(): CollectionInterface { - $embeds = new Collection([], null); + /** @var CollectionInterface $embeds An instance of the collection class implementing CollectionInterface.*/ + $embeds = new ($this->discord->getCollectionClass())([], null); foreach ($this->attributes['embeds'] ?? [] as $embed) { $embeds->pushItem($this->createOf(Embed::class, $embed)); @@ -681,15 +683,15 @@ protected function getEditedTimestampAttribute(): ?Carbon /** * Returns the components attribute. * - * @return Collection|Component[]|null + * @return CollectionInterface|Component[]|null */ - protected function getComponentsAttribute(): ?Collection + protected function getComponentsAttribute(): ?CollectionInterface { if (! isset($this->attributes['components'])) { return null; } - $components = Collection::for(Component::class, null); + $components = ($this->discord->getCollectionClass())::for(Component::class, null); foreach ($this->attributes['components'] as $component) { $components->pushItem($this->createOf(Component::class, $component)); @@ -701,15 +703,15 @@ protected function getComponentsAttribute(): ?Collection /** * Returns the sticker_items attribute. * - * @return Collection|Sticker[]|null Partial stickers. + * @return CollectionInterface|Sticker[]|null Partial stickers. */ - protected function getStickerItemsAttribute(): ?Collection + protected function getStickerItemsAttribute(): ?CollectionInterface { if (! isset($this->attributes['sticker_items']) && ! in_array($this->type, [self::TYPE_DEFAULT, self::TYPE_REPLY])) { return null; } - $sticker_items = Collection::for(Sticker::class); + $sticker_items = ($this->discord->getCollectionClass())::for(Sticker::class); foreach ($this->attributes['sticker_items'] ?? [] as $sticker) { $sticker_items->pushItem($this->factory->part(Sticker::class, (array) $sticker, true)); @@ -1077,12 +1079,13 @@ public function delete(): PromiseInterface * @param int $options['time'] Time in milliseconds until the collector finishes or false. * @param int $options['limit'] The amount of reactions allowed or false. * - * @return PromiseInterface> + * @return PromiseInterface> */ public function createReactionCollector(callable $filter, array $options = []): PromiseInterface { $deferred = new Deferred(); - $reactions = new Collection([], null, null); + /** @var CollectionInterface $reactions An instance of the collection class implementing CollectionInterface.*/ + $reactions = new ($this->discord->getCollectionClass())([], null, null); $timer = null; $options = array_merge([ diff --git a/src/Discord/Parts/Channel/Poll.php b/src/Discord/Parts/Channel/Poll.php index 6420e5242..2f3e07b12 100644 --- a/src/Discord/Parts/Channel/Poll.php +++ b/src/Discord/Parts/Channel/Poll.php @@ -12,7 +12,7 @@ namespace Discord\Parts\Channel; use Carbon\Carbon; -use Discord\Helpers\Collection; +use Discord\Helpers\CollectionInterface; use Discord\Http\Endpoint; use Discord\Parts\Channel\Poll\PollAnswer; use Discord\Parts\Channel\Poll\PollMedia; diff --git a/src/Discord/Parts/Channel/Poll/PollAnswer.php b/src/Discord/Parts/Channel/Poll/PollAnswer.php index 2bfc021a5..b70f525c7 100644 --- a/src/Discord/Parts/Channel/Poll/PollAnswer.php +++ b/src/Discord/Parts/Channel/Poll/PollAnswer.php @@ -11,7 +11,7 @@ namespace Discord\Parts\Channel\Poll; -use Discord\Helpers\Collection; +use Discord\Helpers\CollectionInterface; use Discord\Http\Endpoint; use Discord\Parts\Channel\Channel; use Discord\Parts\Channel\Message; @@ -140,7 +140,7 @@ protected function getGuildAttribute(): ?Guild * * @throws \OutOfRangeException * - * @return PromiseInterface + * @return PromiseInterface */ public function getVoters(array $options = []): PromiseInterface { @@ -162,7 +162,7 @@ public function getVoters(array $options = []): PromiseInterface return $this->http->get($query) ->then(function ($response) { - $users = Collection::for(User::class); + $users = ($this->discord->getCollectionClass())::for(User::class); foreach ($response->users ?? [] as $user) { if (! $part = $this->discord->users->get('id', $user->id)) { diff --git a/src/Discord/Parts/Channel/Reaction.php b/src/Discord/Parts/Channel/Reaction.php index e1a13ff5a..cb0119a3f 100644 --- a/src/Discord/Parts/Channel/Reaction.php +++ b/src/Discord/Parts/Channel/Reaction.php @@ -11,7 +11,7 @@ namespace Discord\Parts\Channel; -use Discord\Helpers\Collection; +use Discord\Helpers\CollectionInterface; use Discord\Http\Endpoint; use Discord\Parts\Guild\Emoji; use Discord\Parts\Guild\Guild; @@ -139,7 +139,7 @@ protected function getIdAttribute(): string * * @link https://discord.com/developers/docs/resources/channel#get-reactions * - * @return PromiseInterface + * @return PromiseInterface */ public function getUsers(array $options = []): PromiseInterface { @@ -161,7 +161,7 @@ public function getUsers(array $options = []): PromiseInterface return $this->http->get($query) ->then(function ($response) { - $users = Collection::for(User::class); + $users = ($this->discord->getCollectionClass())::for(User::class); foreach ((array) $response as $user) { if (! $part = $this->discord->users->get('id', $user->id)) { @@ -182,18 +182,18 @@ public function getUsers(array $options = []): PromiseInterface * * @see Message::getUsers() * - * @return PromiseInterface + * @return PromiseInterface */ public function getAllUsers(): PromiseInterface { - $response = Collection::for(User::class); + $response = ($this->discord->getCollectionClass())::for(User::class); $getUsers = function ($after = null) use (&$getUsers, $response) { $options = ['limit' => 100]; if ($after != null) { $options['after'] = $after; } - return $this->getUsers($options)->then(function (Collection $users) use ($response, &$getUsers) { + return $this->getUsers($options)->then(function (CollectionInterface $users) use ($response, &$getUsers) { $last = null; foreach ($users as $user) { $response->pushItem($user); diff --git a/src/Discord/Parts/Embed/Embed.php b/src/Discord/Parts/Embed/Embed.php index 811635a39..727d9750e 100644 --- a/src/Discord/Parts/Embed/Embed.php +++ b/src/Discord/Parts/Embed/Embed.php @@ -12,7 +12,7 @@ namespace Discord\Parts\Embed; 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; @@ -24,19 +24,19 @@ * * @since 4.0.3 * - * @property string|null $title The title of the embed. - * @property-read string|null $type The type of the embed. - * @property string|null $description A description of the embed. - * @property string|null $url The URL of the embed. - * @property Carbon|null $timestamp A timestamp of the embed. - * @property int|null $color The color of the embed. - * @property Footer|null $footer The footer of the embed. - * @property Image|null $image The image of the embed. - * @property Image|null $thumbnail The thumbnail of the embed. - * @property-read Video|null $video The video of the embed. - * @property-read object|null $provider The provider of the embed. - * @property Author|null $author The author of the embed. - * @property Collection|Field[] $fields A collection of embed fields. + * @property string|null $title The title of the embed. + * @property-read string|null $type The type of the embed. + * @property string|null $description A description of the embed. + * @property string|null $url The URL of the embed. + * @property Carbon|null $timestamp A timestamp of the embed. + * @property int|null $color The color of the embed. + * @property Footer|null $footer The footer of the embed. + * @property Image|null $image The image of the embed. + * @property Image|null $thumbnail The thumbnail of the embed. + * @property-read Video|null $video The video of the embed. + * @property-read object|null $provider The provider of the embed. + * @property Author|null $author The author of the embed. + * @property CollectionInterface|Field[] $fields A collection of embed fields. */ class Embed extends Part { @@ -135,11 +135,11 @@ protected function getAuthorAttribute(): Author /** * Gets the fields attribute. * - * @return Collection|Field[] + * @return CollectionInterface|Field[] */ - protected function getFieldsAttribute(): Collection + protected function getFieldsAttribute(): CollectionInterface { - $fields = Collection::for(Field::class, null); + $fields = ($this->discord->getCollectionClass())::for(Field::class, null); if (! array_key_exists('fields', $this->attributes)) { return $fields; diff --git a/src/Discord/Parts/Guild/AuditLog/AuditLog.php b/src/Discord/Parts/Guild/AuditLog/AuditLog.php index 1cba91e8a..295611446 100644 --- a/src/Discord/Parts/Guild/AuditLog/AuditLog.php +++ b/src/Discord/Parts/Guild/AuditLog/AuditLog.php @@ -11,7 +11,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; @@ -30,14 +30,14 @@ * * @since 5.1.0 * - * @property Collection|Command[] $application_commands List of application commands referenced in the audit log. - * @property Collection|Entry[] $audit_log_entries List of audit log entries. - * @property Collection|Rule[] $auto_moderation_rules List of auto moderation rules referenced in the audit log. - * @property Collection|ScheduledEvent[] $guild_scheduled_events List of guild scheduled events referenced in the audit log. - * @property Collection|Integration[] $integrations List of partial integration objects. - * @property Collection|Thread[] $threads List of threads referenced in the audit log. - * @property Collection|User[] $users List of users referenced in the audit log. - * @property Collection|Webhook[] $webhooks List of webhooks referenced in the audit log. + * @property CollectionInterface|Command[] $application_commands List of application commands referenced in the audit log. + * @property CollectionInterface|Entry[] $audit_log_entries List of audit log entries. + * @property CollectionInterface|Rule[] $auto_moderation_rules List of auto moderation rules referenced in the audit log. + * @property CollectionInterface|ScheduledEvent[] $guild_scheduled_events List of guild scheduled events referenced in the audit log. + * @property CollectionInterface|Integration[] $integrations List of partial integration objects. + * @property CollectionInterface|Thread[] $threads List of threads referenced in the audit log. + * @property CollectionInterface|User[] $users List of users referenced in the audit log. + * @property CollectionInterface|Webhook[] $webhooks List of webhooks referenced in the audit log. * * @property string $guild_id * @property-read Guild|null $guild @@ -74,11 +74,11 @@ protected function getGuildAttribute(): ?Guild /** * Returns a collection of application commands found in the audit log. * - * @return Collection|Command[] + * @return CollectionInterface|Command[] */ - protected function getApplicationCommandsAttribute(): Collection + protected function getApplicationCommandsAttribute(): CollectionInterface { - $collection = Collection::for(Command::class); + $collection = ($this->discord->getCollectionClass())::for(Command::class); foreach ($this->attributes['application_commands'] ?? [] as $application_commands) { $collection->pushItem($this->factory->part(Command::class, (array) $application_commands, true)); @@ -90,11 +90,11 @@ protected function getApplicationCommandsAttribute(): Collection /** * Returns a collection of audit log entries. * - * @return Collection|Entry[] + * @return CollectionInterface|Entry[] */ - protected function getAuditLogEntriesAttribute(): Collection + protected function getAuditLogEntriesAttribute(): CollectionInterface { - $collection = Collection::for(Entry::class); + $collection = ($this->discord->getCollectionClass())::for(Entry::class); foreach ($this->attributes['audit_log_entries'] ?? [] as $entry) { $collection->pushItem($this->createOf(Entry::class, $entry)); @@ -106,11 +106,11 @@ protected function getAuditLogEntriesAttribute(): Collection /** * Returns a collection of auto moderation rules found in the audit log. * - * @return Collection|Rule[] + * @return CollectionInterface|Rule[] */ - protected function getAutoModerationRulesAttribute(): Collection + protected function getAutoModerationRulesAttribute(): CollectionInterface { - $collection = Collection::for(Rule::class); + $collection = ($this->discord->getCollectionClass())::for(Rule::class); foreach ($this->attributes['auto_moderation_rules'] ?? [] as $rule) { $collection->pushItem($this->factory->part(Rule::class, (array) $rule, true)); @@ -122,11 +122,11 @@ protected function getAutoModerationRulesAttribute(): Collection /** * Returns a collection of guild scheduled events found in the audit log. * - * @return Collection|ScheduledEvent[] + * @return CollectionInterface|ScheduledEvent[] */ - protected function getGuildScheduledEventsAttribute(): Collection + protected function getGuildScheduledEventsAttribute(): CollectionInterface { - $collection = Collection::for(ScheduledEvent::class); + $collection = ($this->discord->getCollectionClass())::for(ScheduledEvent::class); foreach ($this->attributes['guild_scheduled_events'] ?? [] as $scheduled_event) { $collection->pushItem($this->factory->part(ScheduledEvent::class, (array) $scheduled_event, true)); @@ -140,11 +140,11 @@ protected function getGuildScheduledEventsAttribute(): Collection * * @link https://discord.com/developers/docs/resources/audit-log#audit-log-object-example-partial-integration-object * - * @return Collection|Integration[] + * @return CollectionInterface|Integration[] */ - protected function getIntegrationsAttribute(): Collection + protected function getIntegrationsAttribute(): CollectionInterface { - $collection = Collection::for(Integration::class); + $collection = ($this->discord->getCollectionClass())::for(Integration::class); foreach ($this->attributes['integrations'] ?? [] as $integration) { $collection->pushItem($this->factory->part(Integration::class, (array) $integration, true)); @@ -156,11 +156,11 @@ protected function getIntegrationsAttribute(): Collection /** * Returns a collection of threads found in the audit log. * - * @return Collection|Thread[] + * @return CollectionInterface|Thread[] */ - protected function getThreadsAttribute(): Collection + protected function getThreadsAttribute(): CollectionInterface { - $collection = Collection::for(Thread::class); + $collection = ($this->discord->getCollectionClass())::for(Thread::class); foreach ($this->attributes['threads'] ?? [] as $thread) { $collection->pushItem($this->factory->part(Thread::class, (array) $thread, true)); @@ -172,11 +172,11 @@ protected function getThreadsAttribute(): Collection /** * Returns a collection of users found in the audit log. * - * @return Collection|User[] + * @return CollectionInterface|User[] */ - protected function getUsersAttribute(): Collection + protected function getUsersAttribute(): CollectionInterface { - $collection = Collection::for(User::class); + $collection = ($this->discord->getCollectionClass())::for(User::class); foreach ($this->attributes['users'] ?? [] as $user) { $collection->pushItem($this->discord->users->get('id', $user->id) ?: $this->factory->part(User::class, (array) $user, true)); @@ -188,11 +188,11 @@ protected function getUsersAttribute(): Collection /** * Returns a collection of webhooks found in the audit log. * - * @return Collection|Webhook[] + * @return CollectionInterface|Webhook[] */ - protected function getWebhooksAttribute(): Collection + protected function getWebhooksAttribute(): CollectionInterface { - $collection = Collection::for(Webhook::class); + $collection = ($this->discord->getCollectionClass())::for(Webhook::class); foreach ($this->attributes['webhooks'] ?? [] as $webhook) { $collection->pushItem($this->factory->part(Webhook::class, (array) $webhook, true)); @@ -208,9 +208,9 @@ protected function getWebhooksAttribute(): Collection * * @throws \InvalidArgumentException * - * @return Collection|Entry[] + * @return CollectionInterface|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..cc03d7a7d 100644 --- a/src/Discord/Parts/Guild/AuditLog/Entry.php +++ b/src/Discord/Parts/Guild/AuditLog/Entry.php @@ -11,7 +11,7 @@ namespace Discord\Parts\Guild\AuditLog; -use Discord\Helpers\Collection; +use Discord\Helpers\CollectionInterface; use Discord\Parts\Part; use Discord\Parts\User\User; @@ -22,14 +22,14 @@ * * @link https://discord.com/developers/docs/resources/audit-log#audit-log-entry-object * - * @property ?string $target_id ID of the affected entity (webhook, user, role, etc.). - * @property Collection $changes Changes made to the target_id. - * @property ?string $user_id The user who made the changes. - * @property-read User|null $user - * @property string $id ID of the entry. - * @property int $action_type Type of action that occurred. - * @property Options|null $options Additional info for certain action types. - * @property string|null $reason The reason for the change (0-512 characters). + * @property ?string $target_id ID of the affected entity (webhook, user, role, etc.). + * @property CollectionInterface $changes Changes made to the target_id. + * @property ?string $user_id The user who made the changes. + * @property-read User|null $user + * @property string $id ID of the entry. + * @property int $action_type Type of action that occurred. + * @property Options|null $options Additional info for certain action types. + * @property string|null $reason The reason for the change (0-512 characters). */ class Entry extends Part { @@ -121,11 +121,11 @@ protected function getUserAttribute(): ?User * * @link https://discord.com/developers/docs/resources/audit-log#audit-log-change-object * - * @return Collection + * @return CollectionInterface */ - protected function getChangesAttribute(): Collection + protected function getChangesAttribute(): CollectionInterface { - return new Collection($this->attributes['changes'] ?? [], 'key', null); + return new ($this->discord->getCollectionClass())($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..239cfc138 100644 --- a/src/Discord/Parts/Guild/AutoModeration/Rule.php +++ b/src/Discord/Parts/Guild/AutoModeration/Rule.php @@ -11,7 +11,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; @@ -39,10 +39,10 @@ * @property int $event_type The rule event type. * @property int $trigger_type The rule trigger type. * @property object $trigger_metadata The rule trigger metadata (may contain `keyword_filter`, `regex_patterns`, `presets`, `allow_list`, `mention_total_limit` and `mention_raid_protection_enabled`). - * @property Collection|Action[] $actions The actions which will execute when the rule is triggered. + * @property CollectionInterface|Action[] $actions The actions which will execute when the rule is triggered. * @property bool $enabled Whether the rule is enabled. - * @property Collection|?Role[] $exempt_roles The role ids that should not be affected by the rule (Maximum of 20). - * @property Collection|?Channel[] $exempt_channels The channel ids that should not be affected by the rule (Maximum of 50). + * @property CollectionInterface|?Role[] $exempt_roles The role ids that should not be affected by the rule (Maximum of 20). + * @property CollectionInterface|?Channel[] $exempt_channels The channel ids that should not be affected by the rule (Maximum of 50). */ class Rule extends Part { @@ -98,11 +98,11 @@ protected function getCreatorAttribute(): ?User /** * Returns the actions attribute. * - * @return Collection|Action[] A collection of actions. + * @return CollectionInterface|Action[] A collection of actions. */ - protected function getActionsAttribute(): Collection + protected function getActionsAttribute(): CollectionInterface { - $actions = Collection::for(Action::class, null); + $actions = ($this->discord->getCollectionClass())::for(Action::class, null); foreach ($this->attributes['actions'] as $action) { $actions->pushItem($this->createOf(Action::class, $action)); @@ -114,11 +114,11 @@ protected function getActionsAttribute(): Collection /** * Returns the exempt roles attribute. * - * @return Collection|?Role[] A collection of roles exempt from the rule. + * @return CollectionInterface|?Role[] A collection of roles exempt from the rule. */ - protected function getExemptRolesAttribute(): Collection + protected function getExemptRolesAttribute(): CollectionInterface { - $roles = new Collection(); + $roles = new ($this->discord->getCollectionClass())(); if (empty($this->attributes['exempt_roles'])) { return $roles; @@ -138,11 +138,11 @@ protected function getExemptRolesAttribute(): Collection /** * Returns the exempt channels attribute. * - * @return Collection|?Channel[] A collection of channels exempt from the rule. + * @return CollectionInterface|?Channel[] A collection of channels exempt from the rule. */ - protected function getExemptChannelsAttribute(): Collection + protected function getExemptChannelsAttribute(): CollectionInterface { - $channels = new Collection(); + $channels = new ($this->discord->getCollectionClass())(); if (empty($this->attributes['exempt_channels'])) { return $channels; diff --git a/src/Discord/Parts/Guild/CommandPermissions.php b/src/Discord/Parts/Guild/CommandPermissions.php index 7d297419b..32a85ec57 100644 --- a/src/Discord/Parts/Guild/CommandPermissions.php +++ b/src/Discord/Parts/Guild/CommandPermissions.php @@ -12,7 +12,7 @@ namespace Discord\Parts\Guild; use Discord\Helpers\BigInt; -use Discord\Helpers\Collection; +use Discord\Helpers\CollectionInterface; use Discord\Parts\Interactions\Command\Permission; use Discord\Parts\Part; @@ -28,7 +28,7 @@ * @property string $application_id The id of the application the command belongs to. * @property string $guild_id The id of the guild. * @property-read Guild|null $guild - * @property Collection|Permission[] $permissions The permissions for the command in the guild. + * @property CollectionInterface|Permission[] $permissions The permissions for the command in the guild. */ class CommandPermissions extends Part { @@ -55,11 +55,11 @@ protected function getGuildAttribute(): ?Guild /** * Gets the permissions attribute. * - * @return Collection|Permission[] A collection of permissions. + * @return CollectionInterface|Permission[] A collection of permissions. */ - protected function getPermissionsAttribute(): Collection + protected function getPermissionsAttribute(): CollectionInterface { - $permissions = Collection::for(Permission::class); + $permissions = ($this->discord->getCollectionClass())::for(Permission::class); foreach ($this->attributes['permissions'] ?? [] as $permission) { $permissions->pushItem($this->factory->part(Permission::class, (array) $permission, true)); diff --git a/src/Discord/Parts/Guild/Emoji.php b/src/Discord/Parts/Guild/Emoji.php index b353ee11b..20ce6d6af 100644 --- a/src/Discord/Parts/Guild/Emoji.php +++ b/src/Discord/Parts/Guild/Emoji.php @@ -11,7 +11,7 @@ namespace Discord\Parts\Guild; -use Discord\Helpers\Collection; +use Discord\Helpers\CollectionInterface; use Discord\Parts\Part; use Discord\Parts\User\User; use Stringable; @@ -25,7 +25,7 @@ * * @property ?string $id The identifier for the emoji. * @property string $name The name of the emoji. - * @property Collection|Role[] $roles The roles that are allowed to use the emoji. + * @property CollectionInterface|Role[] $roles The roles that are allowed to use the emoji. * @property User|null $user User that created this emoji. * @property bool|null $require_colons Whether the emoji requires colons to be triggered. * @property bool|null $managed Whether this emoji is managed by a role. @@ -67,11 +67,12 @@ protected function getGuildAttribute(): ?Guild /** * Returns the roles attribute. * - * @return Collection A collection of roles for the emoji. + * @return CollectionInterface A collection of roles for the emoji. */ - protected function getRolesAttribute(): Collection + protected function getRolesAttribute(): CollectionInterface { - $roles = new Collection(); + /** @var CollectionInterface $roles An instance of the collection class implementing CollectionInterface.*/ + $roles = new ($this->discord->getCollectionClass())(); if (empty($this->attributes['roles'])) { return $roles; diff --git a/src/Discord/Parts/Guild/Guild.php b/src/Discord/Parts/Guild/Guild.php index 215bd8a76..1f6087198 100644 --- a/src/Discord/Parts/Guild/Guild.php +++ b/src/Discord/Parts/Guild/Guild.php @@ -13,7 +13,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; @@ -305,7 +305,7 @@ class Guild extends Part /** * An array of valid regions. * - * @var Collection|null + * @var CollectionInterface|null */ protected $regions; @@ -423,7 +423,7 @@ protected function setStickersAttribute(?array $stickers): void * * @throws NoPermissionsException Missing manage_guild permission. * - * @return PromiseInterface + * @return PromiseInterface */ public function getInvites(): PromiseInterface { @@ -433,7 +433,7 @@ public function getInvites(): PromiseInterface } return $this->http->get(Endpoint::bind(Endpoint::GUILD_INVITES, $this->id))->then(function ($response) { - $invites = Collection::for(Invite::class, 'code'); + $invites = ($this->discord->getCollectionClass())::for(Invite::class, 'code'); foreach ($response as $invite) { $invite = $this->factory->part(Invite::class, (array) $invite, true); @@ -568,11 +568,11 @@ protected function getSplashHashAttribute(): ?string * * @deprecated 10.0.0 Use `$channel->stage_instances` * - * @return Collection|StageInstance[] + * @return CollectionInterface|StageInstance[] */ - protected function getStageInstancesAttribute(): Collection + protected function getStageInstancesAttribute(): CollectionInterface { - $stage_instances = Collection::for(StageInstance::class); + $stage_instances = ($this->discord->getCollectionClass())::for(StageInstance::class); if ($channels = $this->channels) { /** @var Channel */ @@ -744,7 +744,7 @@ protected function getFeatureWelcomeScreenEnabledAttribute(): bool * * @link https://discord.com/developers/docs/resources/voice#list-voice-regions * - * @return PromiseInterface + * @return PromiseInterface */ public function getVoiceRegions(): PromiseInterface { @@ -753,7 +753,7 @@ public function getVoiceRegions(): PromiseInterface } return $this->http->get('voice/regions')->then(function ($regions) { - $regions = new Collection($regions); + $regions = new ($this->discord->getCollectionClass())($regions); $this->regions = $regions; @@ -1155,7 +1155,7 @@ public function updateRolePositions(array $roles): PromiseInterface * @param string|null $options['query'] Query string to match username(s) and nickname(s) against * @param int|null $options['limit'] How many entries are returned (default 1, minimum 1, maximum 1000) * - * @return PromiseInterface + * @return PromiseInterface */ public function searchMembers(array $options): PromiseInterface { @@ -1176,7 +1176,7 @@ public function searchMembers(array $options): PromiseInterface $endpoint->addQuery('limit', $options['limit']); return $this->http->get($endpoint)->then(function ($responses) { - $members = Collection::for(Member::class); + $members = ($this->discord->getCollectionClass())::for(Member::class); foreach ($responses as $response) { if (! $member = $this->members->get('id', $response->user->id)) { diff --git a/src/Discord/Parts/Guild/ScheduledEvent.php b/src/Discord/Parts/Guild/ScheduledEvent.php index 49b571776..e4e3811ff 100644 --- a/src/Discord/Parts/Guild/ScheduledEvent.php +++ b/src/Discord/Parts/Guild/ScheduledEvent.php @@ -12,7 +12,7 @@ namespace Discord\Parts\Guild; use Carbon\Carbon; -use Discord\Helpers\Collection; +use Discord\Helpers\CollectionInterface; use Discord\Http\Endpoint; use Discord\Parts\Channel\Channel; use Discord\Parts\Part; @@ -97,7 +97,7 @@ class ScheduledEvent extends Part * * @throws \RangeException * - * @return PromiseInterface> + * @return PromiseInterface> */ public function getUsers(array $options): PromiseInterface { @@ -126,7 +126,7 @@ public function getUsers(array $options): PromiseInterface } return $this->http->get($endpoint)->then(function ($responses) { - $users = new Collection(); + $users = new ($this->discord->getCollectionClass())(); $guild = $this->guild; diff --git a/src/Discord/Parts/Guild/WelcomeScreen.php b/src/Discord/Parts/Guild/WelcomeScreen.php index 3ea37c850..3e6124273 100644 --- a/src/Discord/Parts/Guild/WelcomeScreen.php +++ b/src/Discord/Parts/Guild/WelcomeScreen.php @@ -11,7 +11,7 @@ namespace Discord\Parts\Guild; -use Discord\Helpers\Collection; +use Discord\Helpers\CollectionInterface; use Discord\Parts\Part; /** @@ -22,7 +22,7 @@ * @since 7.0.0 * * @property ?string $description The server description shown in the welcome screen. - * @property Collection|WelcomeChannel[] $welcome_channels The channels shown in the welcome screen, up to 5. + * @property CollectionInterface|WelcomeChannel[] $welcome_channels The channels shown in the welcome screen, up to 5. */ class WelcomeScreen extends Part { @@ -37,11 +37,11 @@ class WelcomeScreen extends Part /** * Returns the Welcome Channels of the Welcome Screen. * - * @return Collection|WelcomeChannel[] The channels of welcome screen. + * @return CollectionInterface|WelcomeChannel[] The channels of welcome screen. */ - protected function getWelcomeChannelsAttribute(): Collection + protected function getWelcomeChannelsAttribute(): CollectionInterface { - $collection = Collection::for(WelcomeChannel::class, null); + $collection = ($this->discord->getCollectionClass())::for(WelcomeChannel::class, null); foreach ($this->attributes['welcome_channels'] ?? [] as $welcome_channel) { $collection->pushItem($this->createOf(WelcomeChannel::class, $welcome_channel)); diff --git a/src/Discord/Parts/Interactions/Command/Command.php b/src/Discord/Parts/Interactions/Command/Command.php index 139bc83b8..b8cf1594a 100644 --- a/src/Discord/Parts/Interactions/Command/Command.php +++ b/src/Discord/Parts/Interactions/Command/Command.php @@ -11,7 +11,7 @@ namespace Discord\Parts\Interactions\Command; -use Discord\Helpers\Collection; +use Discord\Helpers\CollectionInterface; use Discord\Parts\Guild\Guild; use Discord\Parts\Part; use Stringable; @@ -79,15 +79,15 @@ protected function getApplicationIdAttribute(): string /** * Gets the options attribute. * - * @return Collection|Option[]|null A collection of options. + * @return CollectionInterface|Option[]|null A collection of options. */ - protected function getOptionsAttribute(): ?Collection + protected function getOptionsAttribute(): ?CollectionInterface { if (! isset($this->attributes['options']) && (isset($this->type) && $this->type != self::CHAT_INPUT)) { return null; } - $options = Collection::for(Option::class, null); + $options = ($this->discord->getCollectionClass())::for(Option::class, null); foreach ($this->attributes['options'] ?? [] as $option) { $options->pushItem($this->createOf(Option::class, $option)); diff --git a/src/Discord/Parts/Interactions/Command/Option.php b/src/Discord/Parts/Interactions/Command/Option.php index 6900ff6be..80ea54805 100644 --- a/src/Discord/Parts/Interactions/Command/Option.php +++ b/src/Discord/Parts/Interactions/Command/Option.php @@ -11,7 +11,7 @@ namespace Discord\Parts\Interactions\Command; -use Discord\Helpers\Collection; +use Discord\Helpers\CollectionInterface; use Discord\Parts\Part; use function Discord\poly_strlen; @@ -29,8 +29,8 @@ * @property string $description 1-100 character description. * @property ?string[]|null $description_localizations Localization dictionary for the description field. Values follow the same restrictions as description. * @property bool|null $required If the parameter is required or optional--default false. - * @property Collection|Choice[]|null $choices Choices for STRING, INTEGER, and NUMBER types for the user to pick from, max 25. Only for slash commands. - * @property Collection|Option[] $options Sub-options if applicable. + * @property CollectionInterface|Choice[]|null $choices Choices for STRING, INTEGER, and NUMBER types for the user to pick from, max 25. Only for slash commands. + * @property CollectionInterface|Option[] $options Sub-options if applicable. * @property array|null $channel_types If the option is a channel type, the channels shown will be restricted to these types. * @property int|float|null $min_value If the option is an INTEGER or NUMBER type, the minimum value permitted. * @property int|float|null $max_value If the option is an INTEGER or NUMBER type, the maximum value permitted. @@ -75,15 +75,15 @@ class Option extends Part /** * Gets the choices attribute. * - * @return Collection|Choice[]|null A collection of choices. + * @return CollectionInterface|Choice[]|null A collection of choices. */ - protected function getChoicesAttribute(): ?Collection + protected function getChoicesAttribute(): ?CollectionInterface { if (! isset($this->attributes['choices']) && ! in_array($this->type, [self::STRING, self::INTEGER, self::NUMBER])) { return null; } - $choices = Collection::for(Choice::class, null); + $choices = ($this->discord->getCollectionClass())::for(Choice::class, null); foreach ($this->attributes['choices'] ?? [] as $choice) { $choices->pushItem($this->createOf(Choice::class, $choice)); @@ -95,11 +95,11 @@ protected function getChoicesAttribute(): ?Collection /** * Gets the options attribute. * - * @return Collection|Option[] A collection of options. + * @return CollectionInterface|Option[] A collection of options. */ - protected function getOptionsAttribute(): Collection + protected function getOptionsAttribute(): CollectionInterface { - $options = Collection::for(Option::class, null); + $options = ($this->discord->getCollectionClass())::for(Option::class, null); foreach ($this->attributes['options'] ?? [] as $option) { $options->pushItem($this->createOf(Option::class, $option)); diff --git a/src/Discord/Parts/Interactions/Interaction.php b/src/Discord/Parts/Interactions/Interaction.php index 0def5a361..132b9b1e4 100644 --- a/src/Discord/Parts/Interactions/Interaction.php +++ b/src/Discord/Parts/Interactions/Interaction.php @@ -13,7 +13,7 @@ use Discord\Builders\Components\Component; use Discord\Builders\MessageBuilder; -use Discord\Helpers\Collection; +use Discord\Helpers\CollectionInterface; use Discord\Helpers\Multipart; use Discord\Http\Endpoint; use Discord\Parts\Channel\Channel; @@ -610,7 +610,7 @@ public function showModal(string $title, string $custom_id, array $components, ? if ($submit) { $listener = function (Interaction $interaction) use ($custom_id, $submit, &$listener) { if ($interaction->type == self::TYPE_MODAL_SUBMIT && $interaction->data->custom_id == $custom_id) { - $components = Collection::for(RequestComponent::class, 'custom_id'); + $components = ($this->discord->getCollectionClass())::for(RequestComponent::class, 'custom_id'); foreach ($interaction->data->components as $actionrow) { if ($actionrow->type == Component::TYPE_ACTION_ROW) { foreach ($actionrow->components as $component) { diff --git a/src/Discord/Parts/Interactions/Request/Component.php b/src/Discord/Parts/Interactions/Request/Component.php index a6a7a8a8d..baa311112 100644 --- a/src/Discord/Parts/Interactions/Request/Component.php +++ b/src/Discord/Parts/Interactions/Request/Component.php @@ -12,7 +12,7 @@ namespace Discord\Parts\Interactions\Request; use Discord\Builders\Components\Component as ComponentBuilder; -use Discord\Helpers\Collection; +use Discord\Helpers\CollectionInterface; use Discord\Parts\Guild\Emoji; use Discord\Parts\Part; @@ -36,7 +36,7 @@ * @property string|null $placeholder Custom placeholder text if nothing is selected; max 150 characters. (Select Menus, Text Inputs) * @property int|null $min_values The minimum number of items that must be chosen; default 1, min 0, max 25. (Select Menus) * @property int|null $max_values The maximum number of items that can be chosen; default 1, max 25. (Select Menus) - * @property Collection|Component[]|null $components A list of child components. (Action Rows) + * @property CollectionInterface|Component[]|null $components A list of child components. (Action Rows) * @property int|null $min_length Minimum input length for a text input. (Text Inputs) * @property int|null $max_length Maximum input length for a text input. (Text Inputs) * @property bool|null $required Whether this component is required to be filled; defaults to `true` (Text Inputs) @@ -69,15 +69,15 @@ class Component extends Part /** * Gets the sub-components of the component. * - * @return Collection|Component[]|null $components + * @return CollectionInterface|Component[]|null $components */ - protected function getComponentsAttribute(): ?Collection + protected function getComponentsAttribute(): ?CollectionInterface { if (! isset($this->attributes['components']) && $this->type != ComponentBuilder::TYPE_ACTION_ROW) { return null; } - $components = Collection::for(Component::class, null); + $components = ($this->discord->getCollectionClass())::for(Component::class, null); foreach ($this->attributes['components'] ?? [] as $component) { $components->pushItem($this->createOf(Component::class, $component)); diff --git a/src/Discord/Parts/Interactions/Request/InteractionData.php b/src/Discord/Parts/Interactions/Request/InteractionData.php index b18a2e367..5b1fe2bae 100644 --- a/src/Discord/Parts/Interactions/Request/InteractionData.php +++ b/src/Discord/Parts/Interactions/Request/InteractionData.php @@ -11,7 +11,7 @@ namespace Discord\Parts\Interactions\Request; -use Discord\Helpers\Collection; +use Discord\Helpers\CollectionInterface; use Discord\Parts\Interactions\Command\Command; use Discord\Parts\Part; @@ -26,13 +26,13 @@ * @property string $name Name of the invoked command. * @property int $type The type of the invoked command. * @property Resolved|null $resolved Resolved users, members, roles and channels that are relevant. - * @property Collection|Option[]|null $options Parameters and values from the user. + * @property CollectionInterface|Option[]|null $options Parameters and values from the user. * @property string|null $guild_id ID of the guild internally passed from Interaction or ID of the guild the command belongs to. * @property string|null $target_id ID the of user or message targeted by a user or message command. * @property string|null $custom_id Custom ID the component was created for. (Only for Message Component & Modal) * @property int|null $component_type Type of the component. (Only for Message Component) * @property string[]|null $values Values selected in a select menu. (Only for Message Component) - * @property Collection|Component[]|null $components The values submitted by the user. (Only for Modal) + * @property CollectionInterface|Component[]|null $components The values submitted by the user. (Only for Modal) */ class InteractionData extends Part { @@ -58,15 +58,15 @@ class InteractionData extends Part /** * Gets the options of the interaction. * - * @return Collection|Option[]|null $options + * @return CollectionInterface|Option[]|null $options */ - protected function getOptionsAttribute(): ?Collection + protected function getOptionsAttribute(): ?CollectionInterface { if (! isset($this->attributes['options']) && $this->type != Command::CHAT_INPUT) { return null; } - $options = Collection::for(Option::class, 'name'); + $options = ($this->discord->getCollectionClass())::for(Option::class, 'name'); foreach ($this->attributes['options'] ?? [] as $option) { $options->pushItem($this->createOf(Option::class, $option)); @@ -78,15 +78,15 @@ protected function getOptionsAttribute(): ?Collection /** * Gets the components of the interaction. * - * @return Collection|Component[]|null $components + * @return CollectionInterface|Component[]|null $components */ - protected function getComponentsAttribute(): ?Collection + protected function getComponentsAttribute(): ?CollectionInterface { if (! isset($this->attributes['components'])) { return null; } - $components = Collection::for(Component::class, null); + $components = ($this->discord->getCollectionClass())::for(Component::class, null); foreach ($this->attributes['components'] as $component) { $components->pushItem($this->createOf(Component::class, $component)); diff --git a/src/Discord/Parts/Interactions/Request/Option.php b/src/Discord/Parts/Interactions/Request/Option.php index 05e561280..a26a9eae0 100644 --- a/src/Discord/Parts/Interactions/Request/Option.php +++ b/src/Discord/Parts/Interactions/Request/Option.php @@ -11,7 +11,7 @@ namespace Discord\Parts\Interactions\Request; -use Discord\Helpers\Collection; +use Discord\Helpers\CollectionInterface; use Discord\Parts\Interactions\Command\Option as CommandOption; use Discord\Parts\Part; @@ -25,7 +25,7 @@ * @property string $name Name of the parameter. * @property int $type Type of the option. * @property string|int|float|bool|null $value Value of the option resulting from user input. - * @property Collection|Option[]|null $options Present if this option is a group or subcommand. + * @property CollectionInterface|Option[]|null $options Present if this option is a group or subcommand. * @property bool|null $focused `true` if this option is the currently focused option for autocomplete. */ class Option extends Part @@ -44,15 +44,15 @@ class Option extends Part /** * Gets the options of the interaction. * - * @return Collection|Option[]|null $options + * @return CollectionInterface|Option[]|null $options */ - protected function getOptionsAttribute(): ?Collection + protected function getOptionsAttribute(): ?CollectionInterface { if (! isset($this->attributes['options']) && ! in_array($this->type, [CommandOption::SUB_COMMAND, CommandOption::SUB_COMMAND_GROUP])) { return null; } - $options = Collection::for(Option::class, 'name'); + $options = ($this->discord->getCollectionClass())::for(Option::class, 'name'); foreach ($this->attributes['options'] ?? [] as $option) { $options->pushItem($this->createOf(Option::class, $option)); diff --git a/src/Discord/Parts/Interactions/Request/Resolved.php b/src/Discord/Parts/Interactions/Request/Resolved.php index 12f7ce7fb..fa18c8ebf 100644 --- a/src/Discord/Parts/Interactions/Request/Resolved.php +++ b/src/Discord/Parts/Interactions/Request/Resolved.php @@ -11,7 +11,7 @@ namespace Discord\Parts\Interactions\Request; -use Discord\Helpers\Collection; +use Discord\Helpers\CollectionInterface; use Discord\Parts\Channel\Attachment; use Discord\Parts\Channel\Channel; use Discord\Parts\Channel\Message; @@ -28,12 +28,12 @@ * * @since 7.0.0 * - * @property Collection|User[]|null $users The ids and User objects. - * @property Collection|Member[]|null $members The ids and partial Member objects. - * @property Collection|Role[]|null $roles The ids and Role objects. - * @property Collection|Channel[]|Thread[]|null $channels The ids and partial Channel objects. - * @property Collection|Message[]|null $messages The ids and partial Message objects. - * @property Collection|Attachment[]|null $attachments The ids and partial Attachment objects. + * @property CollectionInterface|User[]|null $users The ids and User objects. + * @property CollectionInterface|Member[]|null $members The ids and partial Member objects. + * @property CollectionInterface|Role[]|null $roles The ids and Role objects. + * @property CollectionInterface|Channel[]|Thread[]|null $channels The ids and partial Channel objects. + * @property CollectionInterface|Message[]|null $messages The ids and partial Message objects. + * @property CollectionInterface|Attachment[]|null $attachments The ids and partial Attachment objects. * * @property string|null $guild_id ID of the guild internally passed from Interaction. */ @@ -62,15 +62,15 @@ class Resolved extends Part /** * Returns a collection of resolved users. * - * @return Collection|User[]|null Map of Snowflakes to user objects + * @return CollectionInterface|User[]|null Map of Snowflakes to user objects */ - protected function getUsersAttribute(): ?Collection + protected function getUsersAttribute(): ?CollectionInterface { if (! isset($this->attributes['users'])) { return null; } - $collection = Collection::for(User::class); + $collection = ($this->discord->getCollectionClass())::for(User::class); foreach ($this->attributes['users'] as $snowflake => $user) { $collection->pushItem($this->discord->users->get('id', $snowflake) ?: $this->factory->part(User::class, (array) $user, true)); @@ -84,15 +84,15 @@ protected function getUsersAttribute(): ?Collection * * Partial Member objects are missing user, deaf and mute fields * - * @return Collection|Member[]|null Map of Snowflakes to partial member objects + * @return CollectionInterface|Member[]|null Map of Snowflakes to partial member objects */ - protected function getMembersAttribute(): ?Collection + protected function getMembersAttribute(): ?CollectionInterface { if (! isset($this->attributes['members'])) { return null; } - $collection = Collection::for(Member::class); + $collection = ($this->discord->getCollectionClass())::for(Member::class); foreach ($this->attributes['members'] as $snowflake => $member) { if ($guild = $this->discord->guilds->get('id', $this->guild_id)) { @@ -113,15 +113,15 @@ protected function getMembersAttribute(): ?Collection /** * Returns a collection of resolved roles. * - * @return Collection|Role[]|null Map of Snowflakes to role objects + * @return CollectionInterface|Role[]|null Map of Snowflakes to role objects */ - protected function getRolesAttribute(): ?Collection + protected function getRolesAttribute(): ?CollectionInterface { if (! isset($this->attributes['roles'])) { return null; } - $collection = Collection::for(Role::class); + $collection = ($this->discord->getCollectionClass())::for(Role::class); foreach ($this->attributes['roles'] as $snowflake => $role) { if ($guild = $this->discord->guilds->get('id', $this->guild_id)) { @@ -143,15 +143,15 @@ protected function getRolesAttribute(): ?Collection * * Partial Channel objects only have id, name, type and permissions fields. Threads will also have thread_metadata and parent_id fields. * - * @return Collection|Channel[]|Thread[]|null Map of Snowflakes to partial channel objects + * @return CollectionInterface|Channel[]|Thread[]|null Map of Snowflakes to partial channel objects */ - protected function getChannelsAttribute(): ?Collection + protected function getChannelsAttribute(): ?CollectionInterface { if (! isset($this->attributes['channels'])) { return null; } - $collection = new Collection(); + $collection = new ($this->discord->getCollectionClass())(); foreach ($this->attributes['channels'] as $snowflake => $channel) { if ($guild = $this->discord->guilds->get('id', $this->guild_id)) { @@ -175,15 +175,15 @@ protected function getChannelsAttribute(): ?Collection /** * Returns a collection of resolved messages. * - * @return Collection|Message[]|null Map of Snowflakes to partial messages objects + * @return CollectionInterface|Message[]|null Map of Snowflakes to partial messages objects */ - protected function getMessagesAttribute(): ?Collection + protected function getMessagesAttribute(): ?CollectionInterface { if (! isset($this->attributes['messages'])) { return null; } - $collection = Collection::for(Message::class); + $collection = ($this->discord->getCollectionClass())::for(Message::class); foreach ($this->attributes['messages'] as $snowflake => $message) { if ($guild = $this->discord->guilds->get('id', $this->guild_id)) { @@ -201,15 +201,15 @@ protected function getMessagesAttribute(): ?Collection /** * Returns a collection of resolved attachments. * - * @return Collection|Attachment[]|null Map of Snowflakes to attachments objects + * @return CollectionInterface|Attachment[]|null Map of Snowflakes to attachments objects */ - protected function getAttachmentsAttribute(): ?Collection + protected function getAttachmentsAttribute(): ?CollectionInterface { if (! isset($this->attributes['attachments'])) { return null; } - $attachments = Collection::for(Attachment::class); + $attachments = ($this->discord->getCollectionClass())::for(Attachment::class); foreach ($this->attributes['attachments'] as $attachment) { $attachments->pushItem($this->factory->part(Attachment::class, (array) $attachment, true)); diff --git a/src/Discord/Parts/Thread/Thread.php b/src/Discord/Parts/Thread/Thread.php index 044d5e605..2580940ae 100644 --- a/src/Discord/Parts/Thread/Thread.php +++ b/src/Discord/Parts/Thread/Thread.php @@ -13,7 +13,7 @@ use Carbon\Carbon; use Discord\Builders\MessageBuilder; -use Discord\Helpers\Collection; +use Discord\Helpers\CollectionInterface; use Discord\Http\Endpoint; use Discord\Http\Exceptions\NoPermissionsException; use Discord\Parts\Channel\Channel; @@ -462,7 +462,7 @@ public function setAutoArchiveDuration(int $duration, ?string $reason = null): P * * @link https://discord.com/developers/docs/resources/channel#get-pinned-messages * - * @return PromiseInterface> + * @return PromiseInterface> * * @todo Make it in a trait along with Channel */ @@ -470,7 +470,7 @@ public function getPinnedMessages(): PromiseInterface { return $this->http->get(Endpoint::bind(Endpoint::CHANNEL_PINS, $this->id)) ->then(function ($responses) { - $messages = Collection::for(Message::class); + $messages = ($this->discord->getCollectionClass())::for(Message::class); foreach ($responses as $response) { $messages->pushItem($this->messages->get('id', $response->id) ?: $this->messages->create($response, true)); @@ -546,7 +546,7 @@ public function deleteMessages($messages, ?string $reason = null): PromiseInterf * @param string|Message|null $options['after'] Get messages after this message ID. * @param int|null $options['limit'] Max number of messages to return (1-100). Defaults to 50. * - * @return PromiseInterface> + * @return PromiseInterface> * * @todo Make it in a trait along with Channel */ @@ -586,7 +586,7 @@ public function getMessageHistory(array $options = []): PromiseInterface } return $this->http->get($endpoint)->then(function ($responses) { - $messages = Collection::for(Message::class); + $messages = ($this->discord->getCollectionClass())::for(Message::class); foreach ($responses as $response) { if (! $message = $this->messages->get('id', $response->id)) { @@ -770,14 +770,14 @@ public function broadcastTyping(): PromiseInterface * @param int $options ['time'] Time in milliseconds until the collector finishes or false. * @param int $options ['limit'] The amount of messages allowed or false. * - * @return PromiseInterface> + * @return PromiseInterface> * * @todo Make it in a trait along with Channel */ public function createMessageCollector(callable $filter, array $options = []): PromiseInterface { $deferred = new Deferred(); - $messages = new Collection([], null, null); + $messages = new ($this->discord->getCollectionClass())([], null, null); $timer = null; $options = array_merge([ diff --git a/src/Discord/Parts/User/Member.php b/src/Discord/Parts/User/Member.php index cdf2088e7..0bceaae52 100644 --- a/src/Discord/Parts/User/Member.php +++ b/src/Discord/Parts/User/Member.php @@ -14,7 +14,7 @@ use Carbon\Carbon; 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; @@ -46,7 +46,7 @@ * @property-read string $displayname The nickname or display name with optional discriminator of the member. * @property ?string|null $avatar The avatar URL of the member or null if member has no guild avatar. * @property ?string|null $avatar_hash The avatar hash of the member or null if member has no guild avatar. - * @property Collection|Role[] $roles A collection of Roles that the member has. + * @property CollectionInterface|Role[] $roles A collection of Roles that the member has. * @property Carbon|null $joined_at A timestamp of when the member joined the guild. * @property Carbon|null $premium_since When the user started boosting the server. * @property bool $deaf Whether the member is deaf. @@ -61,7 +61,7 @@ * @property string $id The unique identifier of the member. * @property string $status The status of the member. * @property-read Activity $game The game the member is playing. - * @property Collection|Activity[] $activities User's current activities. + * @property CollectionInterface|Activity[] $activities User's current activities. * @property object $client_status Current client status. * * @method PromiseInterface sendMessage(MessageBuilder $builder) @@ -609,11 +609,11 @@ protected function getGameAttribute(): ?Activity /** * Gets the activities attribute. * - * @return Collection|Activity[] + * @return CollectionInterface|Activity[] */ - protected function getActivitiesAttribute(): Collection + protected function getActivitiesAttribute(): CollectionInterface { - $activities = Collection::for(Activity::class, null); + $activities = ($this->discord->getCollectionClass())::for(Activity::class, null); foreach ($this->attributes['activities'] ?? [] as $activity) { $activities->pushItem($this->createOf(Activity::class, $activity)); @@ -685,11 +685,11 @@ protected function getGuildAttribute(): ?Guild /** * Returns the roles attribute. * - * @return Collection A collection of roles the member is in. null role only contains ID in the collection. + * @return CollectionInterface 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(); + $roles = new ($this->discord->getCollectionClass())(); if (empty($this->attributes['roles'])) { return $roles; diff --git a/src/Discord/Parts/WebSockets/PresenceUpdate.php b/src/Discord/Parts/WebSockets/PresenceUpdate.php index 911e9306b..ea4dc6f81 100644 --- a/src/Discord/Parts/WebSockets/PresenceUpdate.php +++ b/src/Discord/Parts/WebSockets/PresenceUpdate.php @@ -11,7 +11,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; @@ -32,7 +32,7 @@ * @property string $guild_id The unique identifier of the guild that the presence update affects. * @property-read Guild|null $guild The guild that the presence update affects. * @property string $status The updated status of the user. - * @property Collection|Activity[] $activities The activities of the user. + * @property CollectionInterface|Activity[] $activities The activities of the user. * @property-read Activity $game The updated game of the user. * @property object $client_status Status of the client. * @property string|null $desktop_status Status of the user on their desktop client. Null if they are not active on desktop. @@ -40,7 +40,7 @@ * @property string|null $web_status Status of the user on their web client. Null if they are not active on web. * * @property-read Member $member The member that the presence update affects. - * @property-read Collection|Role[] $roles Roles that the user has in the guild. + * @property-read CollectionInterface|Role[] $roles Roles that the user has in the guild. */ class PresenceUpdate extends Part { @@ -93,11 +93,11 @@ protected function getGuildAttribute(): ?Guild /** * Gets the activities attribute. * - * @return Collection|Activity[] + * @return CollectionInterface|Activity[] */ - protected function getActivitiesAttribute(): Collection + protected function getActivitiesAttribute(): CollectionInterface { - $collection = Collection::for(Activity::class, null); + $collection = ($this->discord->getCollectionClass())::for(Activity::class, null); foreach ($this->attributes['activities'] ?? [] as $activity) { $collection->pushItem($this->factory->part(Activity::class, (array) $activity, true)); @@ -163,14 +163,14 @@ protected function getMemberAttribute(): ?Member /** * Returns the users roles. * - * @return Collection|Role[] + * @return CollectionInterface|Role[] */ - protected function getRolesAttribute(): Collection + protected function getRolesAttribute(): CollectionInterface { if ($member = $this->member) { return $member->roles; } - return Collection::for(Role::class); + return ($this->discord->getCollectionClass())::for(Role::class); } } diff --git a/src/Discord/Repository/AbstractRepository.php b/src/Discord/Repository/AbstractRepository.php index 8cf6fa9ca..b482a9a82 100755 --- a/src/Discord/Repository/AbstractRepository.php +++ b/src/Discord/Repository/AbstractRepository.php @@ -11,7 +11,7 @@ namespace Discord\Repository; -use Discord\Helpers\Collection; +use Discord\Helpers\CollectionInterface; /** * Repositories provide a way to store and update parts on the Discord server. diff --git a/src/Discord/Repository/AbstractRepositoryTrait.php b/src/Discord/Repository/AbstractRepositoryTrait.php index 48b2eb2af..23a6c0628 100644 --- a/src/Discord/Repository/AbstractRepositoryTrait.php +++ b/src/Discord/Repository/AbstractRepositoryTrait.php @@ -577,12 +577,10 @@ public function has(...$keys): bool * @param callable $callback * * @return CollectionInterface - * - * @todo This method will be typed to return a CollectionInterface in v11 */ public function filter(callable $callback) { - $collection = new Collection([], $this->discrim, $this->class); + $collection = new ($this->discord->getCollectionClass())([], $this->discrim, $this->class); foreach ($this->items as $offset => $item) { if ($item instanceof WeakReference) { diff --git a/src/Discord/Repository/Channel/ThreadRepository.php b/src/Discord/Repository/Channel/ThreadRepository.php index e4dabada2..48f7d23b6 100644 --- a/src/Discord/Repository/Channel/ThreadRepository.php +++ b/src/Discord/Repository/Channel/ThreadRepository.php @@ -11,7 +11,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; @@ -87,7 +87,7 @@ protected function cacheFreshen($response): PromiseInterface * * @link https://discord.com/developers/docs/resources/channel#list-active-threads * - * @return PromiseInterface> + * @return PromiseInterface> */ public function active(): PromiseInterface { @@ -109,7 +109,7 @@ public function active(): PromiseInterface * * @throws \InvalidArgumentException * - * @return PromiseInterface> + * @return PromiseInterface> */ public function archived(bool $private = false, bool $joined = false, ?int $limit = null, $before = null): PromiseInterface { @@ -150,11 +150,11 @@ public function archived(bool $private = false, bool $joined = false, ?int $limi * * @param object $response * - * @return Collection|Thread[] + * @return CollectionInterface|Thread[] */ - private function handleThreadPaginationResponse(object $response): Collection + private function handleThreadPaginationResponse(object $response): CollectionInterface { - $collection = Collection::for(Thread::class); + $collection = ($this->discord->getCollectionClass())::for(Thread::class); foreach ($response->threads as $thread) { /** @var Thread */ diff --git a/src/Discord/Voice/VoiceClient.php b/src/Discord/Voice/VoiceClient.php index 398c30d0f..f01d28fa2 100644 --- a/src/Discord/Voice/VoiceClient.php +++ b/src/Discord/Voice/VoiceClient.php @@ -16,7 +16,7 @@ use Discord\Exceptions\LibSodiumNotFoundException; use Discord\Exceptions\OutdatedDCAException; use Discord\Helpers\Buffer as RealBuffer; -use Discord\Helpers\Collection; +use Discord\Helpers\CollectionInterface; use Discord\Parts\Channel\Channel; use Discord\WebSockets\Op; use Evenement\EventEmitter; @@ -371,7 +371,7 @@ public function __construct(WebSocket $websocket, LoopInterface $loop, Channel $ $this->deaf = $data['deaf']; $this->mute = $data['mute']; $this->endpoint = str_replace([':80', ':443'], '', $data['endpoint']); - $this->speakingStatus = new Collection([], 'ssrc'); + $this->speakingStatus = new ($this->discord->getCollectionClass())([], 'ssrc'); $this->dnsConfig = $data['dnsConfig']; } @@ -1341,7 +1341,7 @@ public function close(): void $this->sentLoginFrame = false; $this->startTime = null; $this->streamTime = 0; - $this->speakingStatus = new Collection([], 'ssrc'); + $this->speakingStatus = new ($this->discord->getCollectionClass())([], 'ssrc'); $this->emit('close'); } diff --git a/src/Discord/WebSockets/Events/GuildEmojisUpdate.php b/src/Discord/WebSockets/Events/GuildEmojisUpdate.php index 77dcf0692..ad830ec47 100644 --- a/src/Discord/WebSockets/Events/GuildEmojisUpdate.php +++ b/src/Discord/WebSockets/Events/GuildEmojisUpdate.php @@ -11,7 +11,7 @@ namespace Discord\WebSockets\Events; -use Discord\Helpers\Collection; +use Discord\Helpers\CollectionInterface; use Discord\WebSockets\Event; use Discord\Parts\Guild\Emoji; use Discord\Parts\Guild\Guild; @@ -28,8 +28,8 @@ class GuildEmojisUpdate extends Event */ public function handle($data) { - $oldEmojis = Collection::for(Emoji::class); - $emojiParts = Collection::for(Emoji::class); + $oldEmojis = ($this->discord->getCollectionClass())::for(Emoji::class); + $emojiParts = ($this->discord->getCollectionClass())::for(Emoji::class); /** @var ?Guild */ if ($guild = yield $this->discord->guilds->cacheGet($data->guild_id)) { diff --git a/src/Discord/WebSockets/Events/GuildStickersUpdate.php b/src/Discord/WebSockets/Events/GuildStickersUpdate.php index 966bf7455..2e9c9c40a 100644 --- a/src/Discord/WebSockets/Events/GuildStickersUpdate.php +++ b/src/Discord/WebSockets/Events/GuildStickersUpdate.php @@ -11,7 +11,7 @@ namespace Discord\WebSockets\Events; -use Discord\Helpers\Collection; +use Discord\Helpers\CollectionInterface; use Discord\WebSockets\Event; use Discord\Parts\Guild\Guild; use Discord\Parts\Guild\Sticker; @@ -28,8 +28,8 @@ class GuildStickersUpdate extends Event */ public function handle($data) { - $oldStickers = Collection::for(Sticker::class); - $stickerParts = Collection::for(Sticker::class); + $oldStickers = ($this->discord->getCollectionClass())::for(Sticker::class); + $stickerParts = ($this->discord->getCollectionClass())::for(Sticker::class); /** @var ?Guild */ if ($guild = yield $this->discord->guilds->cacheGet($data->guild_id)) { diff --git a/src/Discord/WebSockets/Events/MessageDeleteBulk.php b/src/Discord/WebSockets/Events/MessageDeleteBulk.php index 99b91972e..c56d3a2c3 100644 --- a/src/Discord/WebSockets/Events/MessageDeleteBulk.php +++ b/src/Discord/WebSockets/Events/MessageDeleteBulk.php @@ -11,7 +11,7 @@ namespace Discord\WebSockets\Events; -use Discord\Helpers\Collection; +use Discord\Helpers\CollectionInterface; use Discord\WebSockets\Event; /** @@ -26,7 +26,7 @@ class MessageDeleteBulk extends Event */ public function handle($data) { - $resolved = new Collection(); + $resolved = new ($this->discord->getCollectionClass())(); foreach ($data->ids as $id) { $event = new MessageDelete($this->discord); diff --git a/src/Discord/WebSockets/Events/ThreadListSync.php b/src/Discord/WebSockets/Events/ThreadListSync.php index 4333274e4..5650277c2 100644 --- a/src/Discord/WebSockets/Events/ThreadListSync.php +++ b/src/Discord/WebSockets/Events/ThreadListSync.php @@ -11,7 +11,7 @@ namespace Discord\WebSockets\Events; -use Discord\Helpers\Collection; +use Discord\Helpers\CollectionInterface; use Discord\Parts\Channel\Channel; use Discord\Parts\Guild\Guild; use Discord\Parts\Thread\Thread; @@ -26,7 +26,7 @@ class ThreadListSync extends Event { public function handle($data) { - $threadParts = Collection::for(Thread::class); + $threadParts = ($this->discord->getCollectionClass())::for(Thread::class); /** @var ?Guild */ if ($guild = yield $this->discord->guilds->cacheGet($data->guild_id)) { diff --git a/tests/Parts/Channel/ChannelTest.php b/tests/Parts/Channel/ChannelTest.php index c5d8772b8..6375fc1fa 100644 --- a/tests/Parts/Channel/ChannelTest.php +++ b/tests/Parts/Channel/ChannelTest.php @@ -13,7 +13,7 @@ use Discord\Builders\MessageBuilder; use Discord\Discord; -use Discord\Helpers\Collection; +use Discord\Helpers\CollectionInterface; use Discord\Parts\Channel\Channel; use Discord\Parts\Channel\Message; use Discord\Parts\Channel\Invite; @@ -36,7 +36,7 @@ public function testCanPinMessageAndGetPinnedMessage() ->then(function () { return $this->channel()->getPinnedMessages(); }) - ->then(function (Collection $messages) use ($message) { + ->then(function (CollectionInterface $messages) use ($message) { $this->assertGreaterThan(0, $messages->count()); $this->assertContains($message->id, $messages->map(function ($message) { return $message->id; @@ -64,7 +64,7 @@ public function testCanPinAndUnpinMessageAndCheckItIsUnpinned() ->then(function () { return $this->channel()->getPinnedMessages(); }) - ->then(function (Collection $messages) use ($message) { + ->then(function (CollectionInterface $messages) use ($message) { $this->assertNotContains($message->id, $messages->map(function ($message) { return $message->id; })); @@ -168,7 +168,7 @@ public function testCanGetMessageHistory() return wait(function (Discord $discord, $resolve) { $this->channel()->getMessageHistory([]) ->then(function ($messages) { - $this->assertInstanceOf(Collection::class, $messages); + $this->assertInstanceOf(CollectionInterface::class, $messages); if ($messages->count() < 1) { $this->markTestSkipped('no messages were present when gettign message history - could not check if collection contained message objects.'); @@ -191,8 +191,8 @@ public function testCanGetInvites() { return wait(function (Discord $discord, $resolve) { $this->channel()->invites->freshen() - ->then(function (Collection $invites) { - $this->assertInstanceOf(Collection::class, $invites); + ->then(function (CollectionInterface $invites) { + $this->assertInstanceOf(CollectionInterface::class, $invites); if ($invites->count() < 1) { $this->markTestSkipped('no invites were present when getting invites - could not check if collection contained invite objects.'); diff --git a/tests/Parts/Channel/Message/EmptyMessageTest.php b/tests/Parts/Channel/Message/EmptyMessageTest.php index 123c94579..c55463bf2 100644 --- a/tests/Parts/Channel/Message/EmptyMessageTest.php +++ b/tests/Parts/Channel/Message/EmptyMessageTest.php @@ -13,7 +13,7 @@ use Carbon\Carbon; use Discord\Discord; -use Discord\Helpers\Collection; +use Discord\Helpers\CollectionInterface; use Discord\Parts\Channel\Channel; use Discord\Parts\Channel\Message; use Discord\Parts\Embed\Embed; @@ -119,19 +119,19 @@ public function testChannelAttribute(Message $message) */ public function testCollectionsEmpty(Message $message) { - $this->assertInstanceOf(Collection::class, $message->mentions); + $this->assertInstanceOf(CollectionInterface::class, $message->mentions); $this->assertEquals(0, $message->mentions->count()); - $this->assertInstanceOf(Collection::class, $message->mention_roles); + $this->assertInstanceOf(CollectionInterface::class, $message->mention_roles); $this->assertEquals(0, $message->mention_roles->count()); - $this->assertInstanceOf(Collection::class, $message->reactions); + $this->assertInstanceOf(CollectionInterface::class, $message->reactions); $this->assertEquals(0, $message->reactions->count()); - $this->assertInstanceOf(Collection::class, $message->mention_channels); + $this->assertInstanceOf(CollectionInterface::class, $message->mention_channels); $this->assertEquals(0, $message->mention_channels->count()); - $this->assertInstanceOf(Collection::class, $message->embeds); + $this->assertInstanceOf(CollectionInterface::class, $message->embeds); $this->assertEquals(0, $message->embeds->count()); }