Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v11 #1271

Draft
wants to merge 17 commits into
base: master
Choose a base branch
from
Draft

v11 #1271

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/Discord/Builders/CommandAttributes.php
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
4 changes: 2 additions & 2 deletions src/Discord/Builders/Components/SelectMenu.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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)) {
Expand Down
41 changes: 30 additions & 11 deletions src/Discord/Discord.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -330,6 +332,13 @@ class Discord
*/
protected $cacheConfig;

/**
* The collection class.
*
* @var string
*/
protected $collectionClass;

/**
* The Client class.
*
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -1408,6 +1421,7 @@ protected function resolveOptions(array $options = []): array
'socket_options',
'dnsConfig',
'cache',
'collection',
])
->setDefaults([
'logger' => null,
Expand All @@ -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])
Expand All @@ -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);

Expand Down Expand Up @@ -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.
*
Expand Down
2 changes: 1 addition & 1 deletion src/Discord/Helpers/RegisteredCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -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])) {
Expand Down
31 changes: 16 additions & 15 deletions src/Discord/Parts/Channel/Channel.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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.
Expand All @@ -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.
Expand Down Expand Up @@ -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));
Expand Down Expand Up @@ -295,13 +295,13 @@ protected function getLastPinTimestampAttribute(): ?Carbon
*
* @link https://discord.com/developers/docs/resources/channel#get-pinned-messages
*
* @return PromiseInterface<Collection<Message[]>>
* @return PromiseInterface<CollectionInterface<Message[]>>
*/
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));
Expand Down Expand Up @@ -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<Collection<Message[]>>
* @return PromiseInterface<CollectionInterface<Message[]>>
* @todo Make it in a trait along with Thread
*/
public function getMessageHistory(array $options = []): PromiseInterface
Expand Down Expand Up @@ -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));
Expand Down Expand Up @@ -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));
Expand Down Expand Up @@ -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<Collection<Message[]>>
* @return PromiseInterface<CollectionInterface<Message[]>>
*/
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([
Expand Down
Loading