├── .gitattributes
├── composer.phar
├── .gitignore
├── .idea
├── vcs.xml
├── .gitignore
├── modules.xml
├── TopPHP.iml
└── php.xml
├── composer.json
├── src
└── TopPHP
│ ├── Structs
│ ├── HttpStruct.php
│ ├── RequestStruct.php
│ └── BaseStruct.php
│ ├── API
│ ├── Exceptions
│ │ ├── MissingTokenException.php
│ │ ├── ResourceRatelimitException.php
│ │ ├── GlobalRatelimitException.php
│ │ └── MissingStatsException.php
│ ├── Http.php
│ └── Request.php
│ └── DBL.php
├── README.md
├── main.php
└── LICENSE
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
--------------------------------------------------------------------------------
/composer.phar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Top-gg-Community/php-sdk/HEAD/composer.phar
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # composer
2 | /vendor
3 | composer.lock
4 |
5 | # regular files
6 | main.php
7 | .TOKEN
8 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /shelf/
3 | /workspace.xml
4 | # Datasource local storage ignored files
5 | /dataSources/
6 | /dataSources.local.xml
7 | # Editor-based HTTP Client requests
8 | /httpRequests/
9 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "top-gg/php-sdk",
3 | "description": "The official Top.gg PHP API wrapper.",
4 | "license": "MIT",
5 | "require": {
6 | "php": "^7.3|^8.0"
7 | },
8 | "authors": [
9 | {
10 | "name": "James Walston",
11 | "email": "james@digicale.com"
12 | }
13 | ],
14 | "autoload": {
15 | "psr-4": {"DBL\\": "src/TopPHP/"}
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/.idea/TopPHP.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/src/TopPHP/Structs/HttpStruct.php:
--------------------------------------------------------------------------------
1 |
26 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # TopPHP
2 | A Top.gg API wrapper written in PHP 8.
3 |
4 | ## Documentation
5 | See [here](https://docs.top.gg/libraries/php/) for the official information.
6 |
7 | ## Installation
8 | TopPHP uses composer to download. In order to install the library, use the following line:
9 |
10 | `composer require top-gg/php-sdk`
11 |
12 | ## Features
13 |
14 | * Working GET and POST requests.
15 | * Enumerable constants for HTTP search lookups.
16 | * Flexible namespaces and interfaces for easily editing.
17 | * Up-to-standard package following the latest PSR.
18 | * Automatic bot statistics POST requests. (Shards, guilds)
19 |
20 | ## Coming Soon
21 |
22 | * Webhooks
23 | * Forced library global rate-limiting.
24 |
--------------------------------------------------------------------------------
/main.php:
--------------------------------------------------------------------------------
1 | $token
27 | ]);
28 |
29 | ?>
30 |
--------------------------------------------------------------------------------
/src/TopPHP/Structs/RequestStruct.php:
--------------------------------------------------------------------------------
1 |
27 |
--------------------------------------------------------------------------------
/.idea/php.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021-present fl0w & Top.gg
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/src/TopPHP/API/Exceptions/MissingTokenException.php:
--------------------------------------------------------------------------------
1 | message = "The API could not make a successful connection due to a missing token. (Do you have a token path specified in the DBL class?)";
38 |
39 | switch($type)
40 | {
41 | case self::THROW_NONE:
42 | break;
43 |
44 | default:
45 | die($this->message);
46 | break;
47 | }
48 | }
49 | }
50 |
51 | ?>
52 |
--------------------------------------------------------------------------------
/src/TopPHP/API/Exceptions/ResourceRatelimitException.php:
--------------------------------------------------------------------------------
1 | message = $message;
39 |
40 | switch($type)
41 | {
42 | case self::THROW_NONE:
43 | break;
44 |
45 | default:
46 | die($this->message);
47 | break;
48 | }
49 | }
50 | }
51 |
52 | ?>
53 |
--------------------------------------------------------------------------------
/src/TopPHP/API/Exceptions/GlobalRatelimitException.php:
--------------------------------------------------------------------------------
1 | message = "You have encountered a global ratelimit. Please refer to the JSON contents for your remaining time.";
38 |
39 | switch($type)
40 | {
41 | case self::THROW_NONE:
42 | break;
43 |
44 | default:
45 | die($this->message);
46 | break;
47 | }
48 | }
49 | }
50 |
51 | ?>
52 |
--------------------------------------------------------------------------------
/src/TopPHP/API/Exceptions/MissingStatsException.php:
--------------------------------------------------------------------------------
1 | message = "The API could not make a successful connection due to missing value(s). (Check for valid value?)";
39 |
40 | switch($type)
41 | {
42 | case self::THROW_NONE:
43 | break;
44 |
45 | default:
46 | die($this->message);
47 | break;
48 | }
49 | }
50 | }
51 |
52 | ?>
53 |
--------------------------------------------------------------------------------
/src/TopPHP/Structs/BaseStruct.php:
--------------------------------------------------------------------------------
1 |
48 |
--------------------------------------------------------------------------------
/src/TopPHP/API/Http.php:
--------------------------------------------------------------------------------
1 | http = $http;
46 | $this->port = $port;
47 | }
48 |
49 | /**
50 | * Calls the HTTP path with a specified request.
51 | * Has to meet with the constants of currently
52 | * accepted HTTP requests compatible with the API.
53 | *
54 | * @param string $type The HTTP request you're using.
55 | * @param string $path The HTTP path you're calling.
56 | * @param array $payload Additional information you want to pass on as JSON.
57 | * @return array
58 | */
59 | public function call(string $type, string $path, array $payload = []): array
60 | {
61 | /**
62 | * Determine the type of call in a temporary
63 | * variable to later pass on as information.
64 | * (PHP 8+ method commented below.)
65 | */
66 | switch($type)
67 | {
68 | case self::POST:
69 | $_type = "POST";
70 | break;
71 |
72 | case self::GET:
73 | $_type = "GET";
74 | break;
75 |
76 | default:
77 | $_type = null;
78 | break;
79 | }
80 |
81 | /*
82 | $_type = match($type)
83 | {
84 | Type\RequestType::POST => "POST",
85 | Type\RequestType::GET => "GET",
86 | "default" => null
87 | };
88 | */
89 |
90 | /** Determine what our response status code is. */
91 | $_headers = ($_type) ? get_headers($path) : "400";
92 | $_response = substr($_headers[0], 9, 3);
93 |
94 | if($_response === "401") $_response = "200"; // This is because the token is not being enforced.
95 | if($_response === "429")
96 | {
97 | /**
98 | * We have two specific ratelimit exceptions here.
99 | * To determine this, the content has to be read
100 | * in order to give the right exception.
101 | *
102 | * For now we'll give a standard Exception, this
103 | * will be updated in the future.
104 | */
105 |
106 | die("You have encountered a rate limit. Please refer to the JSON contents for the remaining time.");
107 | }
108 |
109 | /** Now provide the information for the structure. */
110 | $_path = ($_response === "200") ? $path : null;
111 | $_payload = (!$payload) ? $payload : null;
112 |
113 | /**
114 | * All returned information will be formatted this way.
115 | * This will make grabbing argument values easier
116 | * when handling the HTTP requests.
117 | */
118 | return
119 | [
120 | "type" => $_type,
121 | "path" => $_path,
122 | "status" => $_response,
123 | "json" => $_payload
124 | ];
125 | }
126 |
127 | /**
128 | * Gets the HTTP address.
129 | *
130 | * @return string
131 | */
132 | public function getHttp(): string
133 | {
134 | return $this->http;
135 | }
136 |
137 | /**
138 | * Gets the HTTP communication endpoint.
139 | *
140 | * @return int
141 | */
142 | public function getPort(): int
143 | {
144 | return $this->port;
145 | }
146 | }
147 |
148 | ?>
149 |
--------------------------------------------------------------------------------
/src/TopPHP/API/Request.php:
--------------------------------------------------------------------------------
1 | http = $http;
53 | $this->token = $token;
54 | $this->content = [];
55 | $this->cache = null;
56 | $this->response = null;
57 | }
58 |
59 | /**
60 | * Defines how an HTTP request is inferred on.
61 | * The rule is simple: as long as a URL/URI path
62 | * is given and the response is OK, and path is said
63 | * to be valid, a request will be validated. Otherwise,
64 | * an exception is thrown.
65 | *
66 | * @param string $type The HTTP request you're using.
67 | * @param string $path The HTTP path you're calling.
68 | * @param string $resp An HTTP response to be given when handshake is successful.
69 | * @param int $port The HTTP port you're inferring.
70 | * @param array $json Additional information you want to pass on as JSON.
71 | * @return array
72 | */
73 | public function req(string $type, string $path = null, array $json = [], int $port = self::SERVER_PORT): array
74 | {
75 | $_http = new Http($this->http, $port);
76 | $_path = ($path) ? $_http->getHttp(), $path : null;
77 | $_error = false;
78 | $_request = null;
79 | $_response = null;
80 | $_json = (![]) ? http_build_query($json) : null;
81 |
82 | try
83 | {
84 | /** Ensure headers are restored. */
85 | // header_remove("Content-Type");
86 |
87 | /**
88 | * Set up the HTTP request structure.
89 | * Will contextualize and create how we will interact.
90 | */
91 | $_path = $_path, $_json;
92 | $_struct = [
93 | "http" => [
94 | "method" => $type,
95 | "header" => "Content-Type: application/json" . "\r\n" .
96 | "Authorization: {$this->token}" . "\r\n"
97 | ]
98 | ];
99 | $_struct = @stream_context_create($_struct);
100 |
101 | /**
102 | * Here is where the official request is made
103 | * to receive information.
104 | */
105 | $_request = @file_get_contents($_path, true, $_struct);
106 | if(!$_request) $_error = true;
107 | }
108 |
109 | catch (Exception $error) { return $error; }
110 |
111 | finally
112 | {
113 | if(!$_error)
114 | {
115 | // header("Content-Type: application/json");
116 | // @http_response_code(intval($this->response) + 0);
117 |
118 | $_struct = $_http->call(
119 | $type,
120 | $_path,
121 | json_decode($_request, true)
122 | );
123 | $this->cache = $_struct;
124 |
125 | return $_struct;
126 | }
127 |
128 | else
129 | {
130 | error_reporting(E_ALL);
131 | $_error = error_get_last();
132 |
133 | /**
134 | * We'll need to manually pull the response
135 | * status code for this when the error comes.
136 | */
137 | $_headers = get_headers($_path);
138 | $this->response = $_response = substr($_headers[0], 9, 3);
139 |
140 | $this->content =
141 | [
142 | "type" => $type,
143 | "path" => $_path,
144 | "status" => $_response,
145 | "json" => ["message" => $_error["message"]]
146 | ];
147 |
148 | return $this->content;
149 | }
150 | }
151 | }
152 |
153 | /**
154 | * Gets the HTTP webpage's contents.
155 | *
156 | * @return array
157 | */
158 | public function getContents(): array
159 | {
160 | return $this->content;
161 | }
162 |
163 | /**
164 | * Gets the cache of the last requested interaction.
165 | * It is recommended to save this value into an
166 | * instance when being used for preservation.
167 | *
168 | * @return string
169 | */
170 | public function getCache(): string
171 | {
172 | return $this->cache;
173 | }
174 |
175 | /**
176 | * Gets the HTTP response status.
177 | *
178 | * @return string
179 | */
180 | public function getResponse(): string
181 | {
182 | return $this->response;
183 | }
184 | }
185 |
186 | ?>
187 |
--------------------------------------------------------------------------------
/src/TopPHP/DBL.php:
--------------------------------------------------------------------------------
1 | features =
94 | [
95 | "auto_stats" => [false],
96 | "safety" => false,
97 | "webhook" => []
98 | ];
99 |
100 | if($parameters["auto_stats"]) $this->features["auto_stats"][0] = true;
101 | if($parameters["safety"]) $this->features["safety"] = true;
102 | if($parameters["webhook"]) $this->features["webhook"] = true;
103 | if($parameters["token"]) $this->token = $parameters["token"];
104 | else throw new MissingTokenException();
105 |
106 | $this->http = (!$parameters["webhook"]["url"]) ? Request::SERVER_ADDR : $parameters["webhook"]["url"];
107 | $this->port = (!$parameters["webhook"]["port"]) ? Request::SERVER_PORT : $parameters["webhook"]["port"];
108 | $this->api = new Request($this->token, $this->http);
109 |
110 | /** Proxy an HTTP request to see if it works. */
111 | $_response = $this->api->req("GET", "/users/140862798832861184")["status"];
112 | if($_response === "200") $this->connected = true;
113 |
114 | /** Finally do our feature checks from the parameters list. */
115 | if($parameters["auto_stats"])
116 | {
117 | $this->check_auto_stats(
118 | $parameters["auto_stats"]["url"],
119 | $parameters["auto_stats"]["id"]
120 | );
121 | }
122 |
123 | $this->check_safety();
124 | }
125 |
126 | /**
127 | * Checks if stats should be posted to the website automatically.
128 | * This can only be done for a website URL.
129 | *
130 | * @param string $path The HTTP path you're using.
131 | * @param int $id The bot ID.
132 | * @param array $values A list of values to be automatically posted.
133 | * @return void
134 | */
135 | protected function check_auto_stats(string $path, int $id, array $values)
136 | {
137 | try
138 | {
139 | if($values["shards"]) $_json["shards"] = $values["shards"];
140 | if($values["shard_id"]) $_json["shard_id"] = $values["shard_id"];
141 | if($values["shard_count"]) $_json["shard_count"] = $values["shard_count"];
142 | if($values["server_count"]) $_json["server_count"] = $values["server_count"];
143 | else throw new MissingStatsException();
144 |
145 | $_id = ($id) ? $id : throw new MissingStatsException();
146 | $_url = ($path) ? $path : throw new MissingStatsException();
147 | $_type = Http::BOT;
148 | $_request = $this->api->req("POST", "/{$_type}/{$_id}/stats", $_json)["json"];
149 | }
150 |
151 | catch(Exception $error) { echo $error; }
152 |
153 | finally
154 | {
155 | header("Content-Type: application/json");
156 | echo "";
157 | }
158 | }
159 |
160 | /**
161 | * Checks if the person wants a safety lock on the class.
162 | * Basically runs a very quick magic constant to automatically
163 | * delete the class instance as soon as detected. (Faster way)
164 | *
165 | * @return void
166 | */
167 | protected function check_safety()
168 | {
169 | /** One last time to check. */
170 | if($this->features["safety"]) die();
171 | }
172 |
173 | /**
174 | * Shows the information from the specified type through a query search.
175 | *
176 | * @param string $type The search type.
177 | * @param array $json The JSON query fields, with key:val as assoc.
178 | * @return array
179 | */
180 | public function show_info(string $type, array $json = []): array
181 | {
182 | switch($type)
183 | {
184 | case Http::USER:
185 | $_path = "users";
186 | break;
187 |
188 | case Http::BOT:
189 | $_path = "bots";
190 | break;
191 |
192 | default:
193 | die("Invalid search parameter: {$type}");
194 | break;
195 | }
196 |
197 | return $this->api->req("GET", "/{$type}", $json)["json"];
198 | }
199 |
200 | /**
201 | * Displays the general information about something
202 | * given through the search type.
203 | *
204 | * @param string $type The search type.
205 | * @param int $id The bot/user ID.
206 | * @return array
207 | */
208 | public function find_info(string $type, int $id): array
209 | {
210 | switch($type)
211 | {
212 | case Http::USER:
213 | $_path = "users";
214 | break;
215 |
216 | case Http::BOT:
217 | $_path = "bots";
218 | break;
219 |
220 | default:
221 | die("Invalid search parameter: {$type}");
222 | break;
223 | }
224 |
225 | return $this->api->req("GET", "/{$type}/{$id}")["json"];
226 | }
227 |
228 | /**
229 | * Returns the total votes of the bot.
230 | *
231 | * @param int $id The bot ID.
232 | * @return array
233 | */
234 | public function get_votes(int $id)
235 | {
236 | return $this->api->req("GET", "/bots/{$id}/votes")["json"];
237 | }
238 |
239 | /**
240 | * Returns a boolean check for if a user voted for your bot.
241 | *
242 | * @param int $id The bot user ID.
243 | * @param int $user The user Snowflake ID.
244 | * @return array
245 | */
246 | public function get_user_vote(int $id, int $user): array
247 | {
248 | return $this->api->req("GET", "/bots/{$id}/check", ["userId" => $user])["json"]["voted"];
249 | }
250 |
251 | /**
252 | * Returns the statistics of the bot.
253 | *
254 | * @param int $id The bot ID.
255 | * @return array
256 | */
257 | public function get_stats(int $id): array
258 | {
259 | return $this->api->req("GET", "/bots/{$id}/stats")["json"];
260 | }
261 |
262 | /**
263 | * Posts statistics to the bot's Top.gg page.
264 | *
265 | * @param int $id The bot ID.
266 | * @param array $json The JSON query fields.
267 | * @return array
268 | */
269 | public function post_stats(int $id, array $json): array
270 | {
271 | return $this->api->req("POST", "/bots/{$id}/stats", $json)["json"];
272 | }
273 |
274 | /**
275 | * Returns the current HTTP address.
276 | *
277 | * @return string
278 | */
279 | public function getHttp(): string
280 | {
281 | return $this->http;
282 | }
283 |
284 | /**
285 | * Returns the current HTTP port serial identification.
286 | *
287 | * @return int
288 | */
289 | public function getPort(): int
290 | {
291 | return $this->port;
292 | }
293 |
294 | /**
295 | * Returns the current HTTP request.
296 | *
297 | * @return array
298 | */
299 | public function getContents(): array
300 | {
301 | return $this->api->getContents();
302 | }
303 |
304 | /**
305 | * Returns the last parsed HTTP request.
306 | *
307 | * @return array
308 | */
309 | public function getCache(): array
310 | {
311 | return $this->api->getCache();
312 | }
313 |
314 | /**
315 | * Returns the current HTTP response code.
316 | * (Not to be confused with the cached version in getCache())
317 | *
318 | * @return string
319 | */
320 | public function getResponse(): string
321 | {
322 | return $this->api->getResponse();
323 | }
324 | }
325 |
326 | ?>
327 |
--------------------------------------------------------------------------------