-
-
Notifications
You must be signed in to change notification settings - Fork 239
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
e584be6
commit 93468df
Showing
2 changed files
with
282 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,156 @@ | ||
<?php | ||
|
||
/* | ||
* This file is a part of the DiscordPHP project. | ||
* | ||
* Copyright (c) 2015-present David Cole <[email protected]> | ||
* | ||
* This file is subject to the MIT license that is bundled | ||
* with this source code in the LICENSE.md file. | ||
*/ | ||
|
||
namespace Discord\Parts\Entitlements; | ||
|
||
use Carbon\Carbon; | ||
use Discord\Http\Endpoint; | ||
use Discord\Parts\Part; | ||
use Discord\Parts\User\User; | ||
use Discord\Parts\Guild\Guild; | ||
use React\Promise\ExtendedPromiseInterface; | ||
|
||
/** | ||
* An entitlement object represents a premium offering in the application that a user or guild has access to. | ||
* | ||
* @link https://discord.com/developers/docs/resources/entitlement | ||
* | ||
* @since 10.0.0 | ||
* | ||
* @property string $id ID of the entitlement. | ||
* @property string $sku_id ID of the SKU. | ||
* @property string $application_id ID of the parent application. | ||
* @property string|null $user_id ID of the user that is granted access to the entitlement's SKU. | ||
* @property int $type Type of entitlement. | ||
* @property bool $deleted Entitlement was deleted. | ||
* @property Carbon|null $starts_at Start date at which the entitlement is valid. | ||
* @property Carbon|null $ends_at Date at which the entitlement is no longer valid. | ||
* @property string|null $guild_id ID of the guild that is granted access to the entitlement's SKU. | ||
* @property bool|null $consumed For consumable items, whether or not the entitlement has been consumed. | ||
* @property-read Guild|null $guild The guild that is granted access to the entitlement's SKU. | ||
* @property-read User|null $user The user that is granted access to the entitlement's SKU. | ||
*/ | ||
class Entitlement extends Part | ||
{ | ||
public const OWNER_TYPE_GUILD = 1; | ||
public const OWNER_TYPE_USER = 2; | ||
|
||
public const TYPE_PURCHASE = 1; | ||
public const TYPE_PREMIUM_SUBSCRIPTION = 2; | ||
public const TYPE_DEVELOPER_GIFT = 3; | ||
public const TYPE_TEST_MODE_PURCHASE = 4; | ||
public const TYPE_FREE_PURCHASE = 5; | ||
public const TYPE_USER_GIFT = 6; | ||
public const TYPE_PREMIUM_PURCHASE = 7; | ||
public const TYPE_APPLICATION_SUBSCRIPTION = 8; | ||
|
||
/** | ||
* {@inheritDoc} | ||
*/ | ||
protected $fillable = [ | ||
'id', | ||
'sku_id', | ||
'application_id', | ||
'user_id', | ||
'type', | ||
'deleted', | ||
'starts_at', | ||
'ends_at', | ||
'guild_id', | ||
'consumed', | ||
|
||
// @internal | ||
'guild', | ||
'user', | ||
]; | ||
|
||
/** | ||
* Returns the guild attribute that is granted access to the entitlement's sku. | ||
* | ||
* @return Guild|null | ||
*/ | ||
protected function getGuildAttribute(): ?Guild | ||
{ | ||
return $this->discord->guilds->get('id', $this->guild_id); | ||
} | ||
|
||
/** | ||
* Gets the user that is granted access to the entitlement's sku. | ||
* | ||
* @return User|null | ||
*/ | ||
protected function getUserAttribute(): ?User | ||
{ | ||
return $this->discord->users->get('id', $this->user_id); | ||
} | ||
|
||
/** | ||
* {@inheritDoc} | ||
*/ | ||
public function getRepositoryAttributes(): array | ||
{ | ||
return [ | ||
'application_id' => $this->application_id, | ||
'entitlement_id' => $this->id, | ||
]; | ||
} | ||
|
||
/** | ||
* Returns the starts at attribute. | ||
* | ||
* @return Carbon|null The time that the invite was created. | ||
* | ||
* @throws \Exception | ||
*/ | ||
protected function getStartsAtAttribute(): ?Carbon | ||
{ | ||
if (! isset($this->attributes['starts_at'])) { | ||
return null; | ||
} | ||
|
||
return new Carbon($this->attributes['starts_at']); | ||
} | ||
|
||
/** | ||
* Returns the ends at attribute. | ||
* | ||
* @return Carbon|null The time that the invite was created. | ||
* | ||
* @throws \Exception | ||
*/ | ||
protected function getEndsAtAttribute(): ?Carbon | ||
{ | ||
if (! isset($this->attributes['ends_at'])) { | ||
return null; | ||
} | ||
|
||
return new Carbon($this->attributes['ends_at']); | ||
} | ||
|
||
/** | ||
* Consumes an entitlement. | ||
* | ||
* For One-Time Purchase consumable SKUs, marks a given entitlement for the user as consumed. | ||
* The entitlement will have consumed: true when using List Entitlements. | ||
* | ||
* @param Entitlement $part | ||
* | ||
* @return ExtendedPromiseInterface A promise that resolves to an Entitlement object. | ||
*/ | ||
public function consume(Entitlement $part): ExtendedPromiseInterface | ||
{ | ||
return $this->http->post(Endpoint::bind(Endpoint::APPLICATION_ENTITLEMENT_CONSUME, $this->application_id, $part->id)) | ||
->then(function ($response) use ($part) { // Returns a 204 No Content on success. | ||
$part->consumed = true; | ||
return $part; | ||
}); | ||
} | ||
} |
126 changes: 126 additions & 0 deletions
126
src/Discord/Repository/Entitlements/EntitlementRepository.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
<?php | ||
|
||
/* | ||
* This file is a part of the DiscordPHP project. | ||
* | ||
* Copyright (c) 2015-present David Cole <[email protected]> | ||
* | ||
* This file is subject to the MIT license that is bundled | ||
* with this source code in the LICENSE.md file. | ||
*/ | ||
|
||
namespace Discord\Repository; | ||
|
||
use Discord\Discord; | ||
use Discord\Http\Endpoint; | ||
use Discord\Parts\Entitlements\Entitlement; | ||
use React\Promise\ExtendedPromiseInterface; | ||
|
||
|
||
use function React\Promise\resolve; | ||
|
||
/** | ||
* Contains entitlements of an application. | ||
* | ||
* @see Entitlement | ||
* @see \Discord\Parts\User\Client | ||
* | ||
* @since 10.0.0 | ||
* | ||
* @method Entitlement|null get(string $discrim, $key) | ||
* @method Entitlement|null pull(string|int $key, $default = null) | ||
* @method Entitlement|null first() | ||
* @method Entitlement|null last() | ||
* @method Entitlement|null find(callable $callback) | ||
*/ | ||
class EntitlementRepository extends AbstractRepository | ||
{ | ||
/** | ||
* {@inheritDoc} | ||
*/ | ||
protected $endpoints = [ | ||
'all' => Endpoint::APPLICATION_ENTITLEMENTS, | ||
'get' => Endpoint::APPLICATION_ENTITLEMENT, | ||
'create' => Endpoint::APPLICATION_ENTITLEMENTS, | ||
'delete' => Endpoint::APPLICATION_ENTITLEMENT, | ||
]; | ||
|
||
/** | ||
* {@inheritDoc} | ||
*/ | ||
protected $class = Entitlement::class; | ||
|
||
/** | ||
* {@inheritDoc} | ||
*/ | ||
public function __construct(Discord $discord, array $vars = []) | ||
{ | ||
$vars['application_id'] = $discord->application->id; | ||
|
||
parent::__construct($discord, $vars); | ||
} | ||
|
||
/** | ||
* @param object $response | ||
* | ||
* @return ExtendedPromiseInterface<static> | ||
*/ | ||
protected function cacheFreshen($response): ExtendedPromiseInterface | ||
{ | ||
foreach ($response as $value) foreach ($value as $value) { | ||
$value = array_merge($this->vars, (array) $value); | ||
$part = $this->factory->create($this->class, $value, true); | ||
$items[$part->{$this->discrim}] = $part; | ||
} | ||
|
||
if (empty($items)) { | ||
return resolve($this); | ||
} | ||
|
||
return $this->cache->setMultiple($items)->then(fn ($success) => $this); | ||
} | ||
|
||
/** | ||
* Creates a test entitlement to a given SKU for a given guild or user. | ||
* | ||
* @param string $sku_id ID of the SKU to grant the entitlement to. | ||
* @param string $owner_id ID of the guild or user to grant the entitlement to. | ||
* @param int $owner_type 1 for a guild subscription, 2 for a user subscription. | ||
* | ||
* @throws \InvalidArgumentException | ||
* | ||
* @return ExtendedPromiseInterface<Entitlement> | ||
*/ | ||
public function createTestEntitlement(string $sku_id, string $owner_id, int $owner_type): ExtendedPromiseInterface | ||
{ | ||
$allowed_owner_types = [Entitlement::OWNER_TYPE_GUILD, Entitlement::OWNER_TYPE_USER]; | ||
|
||
if (! in_array($owner_type, $allowed_owner_types)) { | ||
throw new \InvalidArgumentException("The given owner type `{$owner_type}` is not valid."); | ||
} | ||
|
||
$payload = [ | ||
'sku_id' => $sku_id, | ||
'owner_id' => $owner_id, | ||
'owner_type' => $owner_type, | ||
]; | ||
|
||
return $this->http->post(new Endpoint(Endpoint::APPLICATION_ENTITLEMENT), $payload) | ||
->then(fn ($response) => $this->factory->create($this->class, (array) $response, true)); | ||
} | ||
|
||
/* | ||
* Deletes a currently-active test entitlement. | ||
* Discord will act as though that user or guild no longer has entitlement to your premium offering. | ||
* | ||
* @param Entitlement $part | ||
* | ||
* @return ExtendedPromiseInterface | ||
*/ | ||
public function deleteTestEntitlement(Entitlement $part): ExtendedPromiseInterface | ||
{ | ||
return $this->http->delete(Endpoint::bind(Endpoint::APPLICATION_ENTITLEMENT, ['application_id' => $part->application_id, 'entitlement_id' => $part->id])) | ||
->then(fn ($response) => $this->cache->delete($part->{$this->discrim}) | ||
->then(fn ($success) => $part)); | ||
} | ||
} |