| Conditions | 52 |
| Paths | 2 |
| Total Lines | 204 |
| Code Lines | 118 |
| Lines | 0 |
| Ratio | 0 % |
| Changes | 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($this->message->channel->guild !== null && !empty($this->command->clientPermissions)) { |
||
| 232 | $perms = $this->message->channel->permissionsFor($this->message->guild->me); |
||
| 233 | |||
| 234 | $missing = array(); |
||
| 235 | foreach($this->command->clientPermissions as $perm) { |
||
| 236 | if($perms->missing($perm)) { |
||
| 237 | $missing[] = $perm; |
||
| 238 | } |
||
| 239 | } |
||
| 240 | |||
| 241 | if(\count($missing) > 0) { |
||
| 242 | $this->client->emit('commandBlocked', $this, 'clientPermissions'); |
||
| 243 | |||
| 244 | if($this->patternMatches !== null && !((bool) $this->client->getOption('commandBlockedMessagePattern', true))) { |
||
| 245 | return $resolve(); |
||
| 246 | } |
||
| 247 | |||
| 248 | if(\count($missing) === 1) { |
||
| 249 | $msg = 'I need the permissions `'.$missing[0].'` permission for the `'.$this->command->name.'` command to work.'; |
||
| 250 | } else { |
||
| 251 | $missing = \implode(', ', \array_map(function ($perm) { |
||
| 252 | return '`'.\CharlotteDunois\Yasmin\Models\Permissions::resolveToName($perm).'`'; |
||
| 253 | }, $missing)); |
||
| 254 | $msg = 'I need the following permissions for the `'.$this->command->name.'` command to work:'.\PHP_EOL.$missing; |
||
| 255 | } |
||
| 256 | |||
| 257 | return $this->client->dispatcher->throttleNegativeResponseMessage($this, $msg, $resolve, $reject); |
||
| 258 | } |
||
| 259 | } |
||
| 260 | |||
| 261 | // Throttle the command |
||
| 262 | $throttle = $this->command->throttle($this->message->author->id); |
||
| 263 | if($throttle && ($throttle['usages'] + 1) > ($this->command->throttling['usages'])) { |
||
| 264 | $remaining = $throttle['start'] + $this->command->throttling['duration'] - \time(); |
||
| 265 | $this->client->emit('commandBlocked', $this, 'throttling'); |
||
| 266 | |||
| 267 | if($this->patternMatches !== null && !((bool) $this->client->getOption('commandThrottlingMessagePattern', true))) { |
||
| 268 | return $resolve(); |
||
| 269 | } |
||
| 270 | |||
| 271 | return $this->client->dispatcher->throttleNegativeResponseMessage( |
||
| 272 | $this, |
||
| 273 | 'You may not use the `'.$this->command->name.'` command again for another '.$remaining.' seconds.', |
||
| 274 | $resolve, |
||
| 275 | $reject |
||
| 276 | ); |
||
| 277 | } |
||
| 278 | |||
| 279 | // Figure out the command arguments |
||
| 280 | $args = $this->patternMatches; |
||
| 281 | $argmsgs = array(); |
||
| 282 | $countArgs = \count($this->command->args); |
||
| 283 | |||
| 284 | if(!$args && $countArgs > 0) { |
||
| 285 | $count = (!empty($this->command->args[($countArgs - 1)]['infinite']) ? \INF : $countArgs); |
||
| 286 | $provided = self::parseArgs($this->argString, $count, $this->command->argsSingleQuotes); |
||
| 287 | |||
| 288 | $promises[] = $this->command->argsCollector->obtain($this, $provided)->then(function ($result) use (&$args, &$argmsgs) { |
||
| 289 | if($result['cancelled']) { |
||
| 290 | if(\count($result['prompts']) === 0) { |
||
| 291 | throw new \CharlotteDunois\Livia\Exceptions\CommandFormatException($this); |
||
| 292 | } |
||
| 293 | |||
| 294 | $argmsgs = $result['prompts']; |
||
| 295 | $this->client->emit('commandCancelled', $this, $result['cancelled']); |
||
| 296 | |||
| 297 | throw new \CharlotteDunois\Livia\Exceptions\FriendlyException('Cancelled Command.'); |
||
| 298 | } |
||
| 299 | |||
| 300 | $args = $result['values']; |
||
| 301 | $argmsgs = $result['prompts']; |
||
| 302 | |||
| 303 | if(!$args) { |
||
| 304 | $args = $this->parseCommandArgs(); |
||
| 305 | } |
||
| 306 | |||
| 307 | $args = new \ArrayObject(((array) $args), \ArrayObject::ARRAY_AS_PROPS); |
||
| 308 | }); |
||
| 309 | } else { |
||
| 310 | $args = new \ArrayObject(((array) $args), \ArrayObject::ARRAY_AS_PROPS); |
||
| 311 | } |
||
| 312 | |||
| 313 | // Run the command |
||
| 314 | if($throttle) { |
||
| 315 | $this->command->updateThrottle($this->message->author->id); |
||
| 316 | } |
||
| 317 | |||
| 318 | $typingCount = $this->message->channel->typingCount(); |
||
| 319 | |||
| 320 | \React\Promise\all($promises)->then(function () use (&$args, &$argmsgs) { |
||
| 321 | $promise = $this->command->run($this, $args, ($this->patternMatches !== null)); |
||
| 322 | |||
| 323 | if(!($promise instanceof \React\Promise\PromiseInterface)) { |
||
| 324 | $promise = \React\Promise\resolve($promise); |
||
| 325 | } |
||
| 326 | |||
| 327 | $this->client->emit('commandRun', $this->command, $promise, $this, $args, ($this->patternMatches !== null)); |
||
| 328 | |||
| 329 | return $promise->then(function ($response) use (&$argmsgs) { |
||
| 330 | if(!($response instanceof \CharlotteDunois\Yasmin\Models\Message || $response instanceof \CharlotteDunois\Collect\Collection || \is_array($response) || $response === null)) { |
||
| 331 | 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.'); |
||
| 332 | } |
||
| 333 | |||
| 334 | if(!\is_array($response) && !($response instanceof \CharlotteDunois\Collect\Collection)) { |
||
| 335 | if($response instanceof \CharlotteDunois\Yasmin\Models\Message) { |
||
| 336 | $argmsgs[] = $response; |
||
| 337 | } |
||
| 338 | |||
| 339 | return $argmsgs; |
||
| 340 | } |
||
| 341 | |||
| 342 | foreach($response as &$val) { |
||
| 343 | if(!($val instanceof \React\Promise\PromiseInterface)) { |
||
| 344 | $val = \React\Promise\resolve($val); |
||
| 345 | } |
||
| 346 | } |
||
| 347 | |||
| 348 | return \React\Promise\all($response)->then(function ($msgs) use (&$argmsgs) { |
||
| 349 | return \array_merge($argmsgs, $msgs); |
||
| 350 | }); |
||
| 351 | }); |
||
| 352 | })->otherwise(function ($error) use (&$args, $typingCount, &$argmsgs) { |
||
| 353 | if($this->message->channel->typingCount() > $typingCount) { |
||
| 354 | $this->message->channel->stopTyping(); |
||
| 355 | } |
||
| 356 | |||
| 357 | if($error instanceof \CharlotteDunois\Livia\Exceptions\FriendlyException) { |
||
| 358 | return $this->reply($error->getMessage())->then(function (\CharlotteDunois\Yasmin\Models\Message $msg) use (&$argmsgs) { |
||
| 359 | $argmsgs[] = $msg; |
||
| 360 | return $argmsgs; |
||
| 361 | }); |
||
| 362 | } |
||
| 363 | |||
| 364 | $this->client->emit('commandError', $this->command, $error, $this, $args, ($this->patternMatches !== null)); |
||
| 365 | |||
| 366 | $owners = $this->client->owners; |
||
| 367 | $ownersLength = \count($owners); |
||
| 368 | |||
| 369 | if($ownersLength > 0) { |
||
| 370 | $index = 0; |
||
| 371 | $owners = \array_map(function ($user) use ($index, $ownersLength) { |
||
| 372 | $or = ($ownersLength > 1 && $index === ($ownersLength - 1) ? 'or ' : ''); |
||
| 373 | $index++; |
||
| 374 | |||
| 375 | return $or.\CharlotteDunois\Yasmin\Utils\MessageHelpers::escapeMarkdown($user->tag); |
||
| 376 | }, $owners); |
||
| 377 | |||
| 378 | $owners = \implode((\count($owners) > 2 ? ', ' : ' '), $owners); |
||
| 379 | } else { |
||
| 380 | $owners = 'the bot owner'; |
||
| 381 | } |
||
| 382 | |||
| 383 | return $this->reply('An error occurred while running the command: `'.\get_class($error).': '.\str_replace('`', '', $error->getMessage()).'`'.\PHP_EOL. |
||
| 384 | 'You shouldn\'t ever receive an error like this.'.\PHP_EOL. |
||
| 385 | 'Please contact '.$owners.($this->client->getOption('invite') ? ' in this server: '.$this->client->getOption('invite') : '.')) |
||
| 386 | ->then(function (\CharlotteDunois\Yasmin\Models\Message $msg) use (&$argmsgs) { |
||
| 387 | $argmsgs[] = $msg; |
||
| 388 | return $argmsgs; |
||
| 389 | }); |
||
| 390 | })->done($resolve, $reject); |
||
| 391 | })); |
||
| 714 |