Conditions | 53 |
Paths | 2 |
Total Lines | 213 |
Code Lines | 125 |
Lines | 0 |
Ratio | 0 % |
Changes | 1 | ||
Bugs | 0 | Features | 0 |
Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.
For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.
Commonly applied refactorings include:
If many parameters/temporary variables are present:
1 | <?php |
||
187 | function run() { |
||
188 | if($this->command === null) { |
||
189 | throw new \LogicException('This message has no command'); |
||
190 | } |
||
191 | |||
192 | return (new \React\Promise\Promise(function (callable $resolve, callable $reject) { |
||
193 | $promises = array(); |
||
194 | |||
195 | // Obtain the member if we don't have it |
||
196 | if($this->message->guild !== null && !$this->message->guild->members->has($this->message->author->id) && $this->message->webhookID === null) { |
||
197 | $promises[] = $this->message->guild->fetchMember($this->message->author->id); |
||
198 | } |
||
199 | |||
200 | // Obtain the member for the client user if we don't have it |
||
201 | if($this->message->guild !== null && $this->message->guild->me === null) { |
||
202 | $promises[] = $this->message->guild->fetchMember($this->client->user->id); |
||
203 | } |
||
204 | |||
205 | if($this->command->guildOnly && $this->message->guild === null) { |
||
206 | $this->client->emit('commandBlocked', $this, 'guildOnly'); |
||
207 | return $this->client->dispatcher->throttleNegativeResponseMessage($this, 'The `'.$this->command->name.'` command must be used in a server channel.', $resolve, $reject); |
||
208 | } |
||
209 | |||
210 | if($this->command->nsfw && !($this->message->channel->nsfw ?? true)) { |
||
211 | $this->client->emit('commandBlocked', $this, 'nsfw'); |
||
212 | return $this->client->dispatcher->throttleNegativeResponseMessage($this, 'The `'.$this->command->name.'` command must be used in NSFW channels.', $resolve, $reject); |
||
213 | } |
||
214 | |||
215 | $perms = $this->command->hasPermission($this); |
||
216 | if($perms === false || \is_string($perms)) { |
||
217 | $this->client->emit('commandBlocked', $this, 'permission'); |
||
218 | |||
219 | if($this->patternMatches !== null && !((bool) $this->client->getOption('commandBlockedMessagePattern', true))) { |
||
220 | return $resolve(); |
||
221 | } |
||
222 | |||
223 | if($perms === false) { |
||
224 | $perms = 'You do not have permission to use the `'.$this->command->name.'` command.'; |
||
225 | } |
||
226 | |||
227 | return $this->client->dispatcher->throttleNegativeResponseMessage($this, $perms, $resolve, $reject); |
||
228 | } |
||
229 | |||
230 | // Ensure the client user has the required permissions |
||
231 | if( |
||
232 | $this->message->channel instanceof \CharlotteDunois\Yasmin\Interfaces\GuildChannelInterface && |
||
233 | $this->message->channel->guild !== null && |
||
234 | !empty($this->command->clientPermissions) |
||
235 | ) { |
||
236 | $perms = $this->message->channel->permissionsFor($this->message->guild->me); |
||
237 | |||
238 | $missing = array(); |
||
239 | foreach($this->command->clientPermissions as $perm) { |
||
240 | if($perms->missing($perm)) { |
||
241 | $missing[] = $perm; |
||
242 | } |
||
243 | } |
||
244 | |||
245 | if(\count($missing) > 0) { |
||
246 | $this->client->emit('commandBlocked', $this, 'clientPermissions'); |
||
247 | |||
248 | if($this->patternMatches !== null && !((bool) $this->client->getOption('commandBlockedMessagePattern', true))) { |
||
249 | return $resolve(); |
||
250 | } |
||
251 | |||
252 | if(\count($missing) === 1) { |
||
253 | $msg = 'I need the permissions `'.$missing[0].'` permission for the `'.$this->command->name.'` command to work.'; |
||
254 | } else { |
||
255 | $missing = \implode(', ', \array_map(function ($perm) { |
||
256 | return '`'.\CharlotteDunois\Yasmin\Models\Permissions::resolveToName($perm).'`'; |
||
257 | }, $missing)); |
||
258 | $msg = 'I need the following permissions for the `'.$this->command->name.'` command to work:'.\PHP_EOL.$missing; |
||
259 | } |
||
260 | |||
261 | return $this->client->dispatcher->throttleNegativeResponseMessage($this, $msg, $resolve, $reject); |
||
262 | } |
||
263 | } |
||
264 | |||
265 | // Throttle the command |
||
266 | $throttle = $this->command->throttle($this->message->author->id); |
||
267 | if($throttle && ($throttle['usages'] + 1) > ($this->command->throttling['usages'])) { |
||
268 | $remaining = $throttle['start'] + $this->command->throttling['duration'] - \time(); |
||
269 | $this->client->emit('commandBlocked', $this, 'throttling'); |
||
270 | |||
271 | if($this->patternMatches !== null && !((bool) $this->client->getOption('commandThrottlingMessagePattern', true))) { |
||
272 | return $resolve(); |
||
273 | } |
||
274 | |||
275 | return $this->client->dispatcher->throttleNegativeResponseMessage( |
||
276 | $this, |
||
277 | 'You may not use the `'.$this->command->name.'` command again for another '.$remaining.' seconds.', |
||
278 | $resolve, |
||
279 | $reject |
||
280 | ); |
||
281 | } |
||
282 | |||
283 | // Figure out the command arguments |
||
284 | $args = $this->patternMatches; |
||
285 | $argmsgs = array(); |
||
286 | $countArgs = \count($this->command->args); |
||
287 | |||
288 | if(!$args && $countArgs > 0) { |
||
289 | $count = (!empty($this->command->args[($countArgs - 1)]['infinite']) ? \INF : $countArgs); |
||
290 | $provided = self::parseArgs($this->argString, $count, $this->command->argsSingleQuotes); |
||
291 | |||
292 | $promises[] = $this->command->argsCollector->obtain($this, $provided)->then(function ($result) use (&$args, &$argmsgs) { |
||
293 | if($result['cancelled']) { |
||
294 | if(\count($result['prompts']) === 0) { |
||
295 | throw new \CharlotteDunois\Livia\Exceptions\CommandFormatException($this); |
||
296 | } |
||
297 | |||
298 | $argmsgs = $result['prompts']; |
||
299 | $this->client->emit('commandCancelled', $this, $result['cancelled']); |
||
300 | |||
301 | throw new \CharlotteDunois\Livia\Exceptions\FriendlyException('Cancelled Command.'); |
||
302 | } |
||
303 | |||
304 | $args = $result['values']; |
||
305 | $argmsgs = $result['prompts']; |
||
306 | |||
307 | if(!$args) { |
||
308 | $args = $this->parseCommandArgs(); |
||
309 | } |
||
310 | |||
311 | $args = new \ArrayObject(((array) $args), \ArrayObject::ARRAY_AS_PROPS); |
||
312 | }); |
||
313 | } else { |
||
314 | $args = new \ArrayObject(((array) $args), \ArrayObject::ARRAY_AS_PROPS); |
||
315 | } |
||
316 | |||
317 | // Run the command |
||
318 | if($throttle) { |
||
319 | $this->command->updateThrottle($this->message->author->id); |
||
320 | } |
||
321 | |||
322 | $typingCount = $this->message->channel->typingCount(); |
||
323 | |||
324 | \React\Promise\all($promises)->then(function () use (&$args, &$argmsgs) { |
||
325 | $promise = $this->command->run($this, $args, ($this->patternMatches !== null)); |
||
326 | |||
327 | if(!($promise instanceof \React\Promise\PromiseInterface)) { |
||
328 | $promise = \React\Promise\resolve($promise); |
||
329 | } |
||
330 | |||
331 | $this->client->emit('commandRun', $this->command, $promise, $this, $args, ($this->patternMatches !== null)); |
||
332 | |||
333 | return $promise->then(function ($response) use (&$argmsgs) { |
||
334 | if(!( |
||
335 | $response instanceof \CharlotteDunois\Yasmin\Models\Message || |
||
336 | $response instanceof \CharlotteDunois\Collect\Collection || |
||
337 | \is_array($response) || |
||
338 | $response === null |
||
339 | )) { |
||
340 | throw new \RuntimeException('Command '.$this->command->name.'\'s run() resolved with an unknown type ('.\gettype($response).'). Command run methods must return a Promise that resolve with a Message, an array of Messages, a Collection of Messages, or null.'); |
||
341 | } |
||
342 | |||
343 | if(!\is_array($response) && !($response instanceof \CharlotteDunois\Collect\Collection)) { |
||
344 | if($response instanceof \CharlotteDunois\Yasmin\Models\Message) { |
||
345 | $argmsgs[] = $response; |
||
346 | } |
||
347 | |||
348 | return $argmsgs; |
||
349 | } |
||
350 | |||
351 | foreach($response as &$val) { |
||
352 | if(!($val instanceof \React\Promise\PromiseInterface)) { |
||
353 | $val = \React\Promise\resolve($val); |
||
354 | } |
||
355 | } |
||
356 | |||
357 | return \React\Promise\all($response)->then(function ($msgs) use (&$argmsgs) { |
||
358 | return \array_merge($argmsgs, $msgs); |
||
359 | }); |
||
360 | }); |
||
361 | })->then(null, function (\Throwable $error) use (&$args, $typingCount, &$argmsgs) { |
||
362 | if($this->message->channel->typingCount() > $typingCount) { |
||
363 | $this->message->channel->stopTyping(); |
||
364 | } |
||
365 | |||
366 | if($error instanceof \CharlotteDunois\Livia\Exceptions\FriendlyException) { |
||
367 | return $this->reply($error->getMessage())->then(function (\CharlotteDunois\Yasmin\Models\Message $msg) use (&$argmsgs) { |
||
368 | $argmsgs[] = $msg; |
||
369 | return $argmsgs; |
||
370 | }); |
||
371 | } |
||
372 | |||
373 | $this->client->emit('commandError', $this->command, $error, $this, $args, ($this->patternMatches !== null)); |
||
374 | |||
375 | $owners = $this->client->owners; |
||
376 | $ownersLength = \count($owners); |
||
377 | |||
378 | if($ownersLength > 0) { |
||
379 | $index = 0; |
||
380 | $owners = \array_map(function ($user) use (&$index, $ownersLength) { |
||
381 | $or = ($ownersLength > 1 && $index === ($ownersLength - 1) ? 'or ' : ''); |
||
382 | $index++; |
||
383 | |||
384 | return $or.\CharlotteDunois\Yasmin\Utils\MessageHelpers::escapeMarkdown($user->tag); |
||
385 | }, $owners); |
||
386 | |||
387 | $owners = \implode((\count($owners) > 2 ? ', ' : ' '), $owners); |
||
388 | } else { |
||
389 | $owners = 'the bot owner'; |
||
390 | } |
||
391 | |||
392 | return $this->reply('An error occurred while running the command: `'.\get_class($error).': '.\str_replace('`', '', $error->getMessage()).'`'.\PHP_EOL. |
||
393 | 'You shouldn\'t ever receive an error like this.'.\PHP_EOL. |
||
394 | 'Please contact '.$owners.($this->client->getOption('invite') ? ' in this server: '.$this->client->getOption('invite') : '.')) |
||
395 | ->then(function (\CharlotteDunois\Yasmin\Models\Message $msg) use (&$argmsgs) { |
||
396 | $argmsgs[] = $msg; |
||
397 | return $argmsgs; |
||
398 | }); |
||
399 | })->done($resolve, $reject); |
||
400 | })); |
||
721 |