friendship ended with social-app. php is my new best friend
1<?php 2/** 3 * Class Reddit 4 * 5 * @created 09.04.2024 6 * @author smiley <smiley@chillerlan.net> 7 * @copyright 2024 smiley 8 * @license MIT 9 * 10 * @noinspection PhpUnused 11 */ 12declare(strict_types=1); 13 14namespace chillerlan\OAuth\Providers; 15 16use chillerlan\OAuth\Core\{ 17 AuthenticatedUser, ClientCredentials, ClientCredentialsTrait, CSRFToken, OAuth2Interface, 18 OAuth2Provider, TokenInvalidate, TokenInvalidateTrait, TokenRefresh, UserInfo, 19}; 20use Psr\Http\Message\ResponseInterface; 21use function sprintf; 22 23/** 24 * Reddit OAuth2 25 * 26 * @link https://github.com/reddit-archive/reddit/wiki/OAuth2 27 * @link https://github.com/reddit-archive/reddit/wiki/API 28 * @link https://support.reddithelp.com/hc/en-us/articles/16160319875092-Reddit-Data-API-Wiki 29 * @link https://github.com/reddit-archive/reddit/wiki/OAuth2#manually-revoking-a-token 30 * @link https://www.reddit.com/dev/api 31 */ 32class Reddit extends OAuth2Provider implements ClientCredentials, CSRFToken, TokenRefresh, TokenInvalidate, UserInfo{ 33 use ClientCredentialsTrait, TokenInvalidateTrait; 34 35 public const IDENTIFIER = 'REDDIT'; 36 37 public const SCOPE_ACCOUNT = 'account'; 38 public const SCOPE_CREDDITS = 'creddits'; 39 public const SCOPE_EDIT = 'edit'; 40 public const SCOPE_FLAIR = 'flair'; 41 public const SCOPE_HISTORY = 'history'; 42 public const SCOPE_IDENTITY = 'identity'; 43 public const SCOPE_LIVEMANAGE = 'livemanage'; 44 public const SCOPE_MODCONFIG = 'modconfig'; 45 public const SCOPE_MODCONTRIBUTORS = 'modcontributors'; 46 public const SCOPE_MODFLAIR = 'modflair'; 47 public const SCOPE_MODLOG = 'modlog'; 48 public const SCOPE_MODMAIL = 'modmail'; 49 public const SCOPE_MODNOTE = 'modnote'; 50 public const SCOPE_MODOTHERS = 'modothers'; 51 public const SCOPE_MODPOSTS = 'modposts'; 52 public const SCOPE_MODSELF = 'modself'; 53 public const SCOPE_MODTRAFFIC = 'modtraffic'; 54 public const SCOPE_MODWIKI = 'modwiki'; 55 public const SCOPE_MYSUBREDDITS = 'mysubreddits'; 56 public const SCOPE_PRIVATEMESSAGES = 'privatemessages'; 57 public const SCOPE_READ = 'read'; 58 public const SCOPE_REPORT = 'report'; 59 public const SCOPE_SAVE = 'save'; 60 public const SCOPE_STRUCTUREDSTYLES = 'structuredstyles'; 61 public const SCOPE_SUBMIT = 'submit'; 62 public const SCOPE_SUBSCRIBE = 'subscribe'; 63 public const SCOPE_VOTE = 'vote'; 64 public const SCOPE_WIKIEDIT = 'wikiedit'; 65 public const SCOPE_WIKIREAD = 'wikiread'; 66 67 public const DEFAULT_SCOPES = [ 68 self::SCOPE_ACCOUNT, 69 self::SCOPE_IDENTITY, 70 self::SCOPE_READ, 71 ]; 72 73 public const USER_AGENT = OAuth2Interface::USER_AGENT.' (by /u/chillerlan)'; 74 75 public const HEADERS_AUTH = [ 76 'User-Agent' => self::USER_AGENT, 77 ]; 78 79 public const HEADERS_API = [ 80 'User-Agent' => self::USER_AGENT, 81 ]; 82 83 public const USES_BASIC_AUTH_IN_ACCESS_TOKEN_REQUEST = true; 84 85 protected string $authorizationURL = 'https://www.reddit.com/api/v1/authorize'; 86 protected string $accessTokenURL = 'https://www.reddit.com/api/v1/access_token'; 87 protected string $apiURL = 'https://oauth.reddit.com/api'; 88 protected string $revokeURL = 'https://www.reddit.com/api/v1/revoke_token'; 89 protected string|null $apiDocs = 'https://www.reddit.com/dev/api'; 90 protected string|null $applicationURL = 'https://www.reddit.com/prefs/apps/'; 91 protected string|null $userRevokeURL = 'https://www.reddit.com/settings/privacy'; 92 93 /** 94 * @param array<string, scalar|bool|null> $body 95 */ 96 protected function sendTokenInvalidateRequest(string $url, array $body):ResponseInterface{ // phpcs:ignore 97 98 $request = $this->requestFactory 99 ->createRequest('POST', $url) 100 ->withHeader('Content-Type', 'application/x-www-form-urlencoded') 101 ; 102 103 $request = $this->addBasicAuthHeader($request); 104 $request = $this->setRequestBody($body, $request); 105 106 return $this->http->sendRequest($request); 107 } 108 109 /** @codeCoverageIgnore */ 110 public function me():AuthenticatedUser{ 111 $json = $this->getMeResponseData('/v1/me'); 112 113 $userdata = [ 114 'data' => $json, 115 'avatar' => $json['subreddit']['icon_img'], 116 'handle' => $json['name'], 117 'displayName' => $json['subreddit']['title'], 118 'id' => $json['id'], 119 'url' => sprintf('https://www.reddit.com%s', $json['subreddit']['url']), 120 ]; 121 122 return new AuthenticatedUser($userdata); 123 } 124 125}