| Total Complexity | 142 |
| Total Lines | 690 |
| Duplicated Lines | 0 % |
| Changes | 0 | ||
Complex classes like Context often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use Context, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 22 | class Context extends \CharlotteDunois\Yasmin\Models\ClientBase { |
||
| 23 | /** |
||
| 24 | * The client which initiated the instance. |
||
| 25 | * @var \CharlotteDunois\Livia\LiviaClient |
||
| 26 | */ |
||
| 27 | protected $client; |
||
| 28 | |||
| 29 | /** |
||
| 30 | * The message that triggers the command. |
||
| 31 | * @var \CharlotteDunois\Yasmin\Models\Message |
||
| 32 | */ |
||
| 33 | protected $message; |
||
| 34 | |||
| 35 | /** |
||
| 36 | * The command that got triggered, if any. |
||
| 37 | * @var \CharlotteDunois\Livia\Commands\Command|null |
||
| 38 | */ |
||
| 39 | protected $command; |
||
| 40 | |||
| 41 | /** |
||
| 42 | * Argument string for the command. |
||
| 43 | * @var string|null |
||
| 44 | */ |
||
| 45 | protected $argString; |
||
| 46 | |||
| 47 | /** |
||
| 48 | * Pattern matches (if from a pattern trigger). |
||
| 49 | * @var string[]|null |
||
| 50 | */ |
||
| 51 | protected $patternMatches; |
||
| 52 | |||
| 53 | /** |
||
| 54 | * Command responses, as multidimensional array (channelID|dm => Message[]). |
||
| 55 | * @var array |
||
| 56 | */ |
||
| 57 | protected $responses = array(); |
||
| 58 | |||
| 59 | /** |
||
| 60 | * Internal command for serialization. |
||
| 61 | * @var string|null |
||
| 62 | */ |
||
| 63 | protected $internalCommand; |
||
| 64 | |||
| 65 | /** |
||
| 66 | * @internal |
||
| 67 | */ |
||
| 68 | function __construct(\CharlotteDunois\Livia\LiviaClient $client, \CharlotteDunois\Yasmin\Models\Message $message, \CharlotteDunois\Livia\Commands\Command $command = null, string $argString = null, array $patternMatches = null) { |
||
| 69 | $this->client = $client; |
||
| 70 | $this->message = $message; |
||
| 71 | $this->command = $command; |
||
| 72 | |||
| 73 | $this->argString = ($argString !== null ? \trim($argString) : null); |
||
| 74 | $this->patternMatches = $patternMatches; |
||
| 75 | } |
||
| 76 | |||
| 77 | /** |
||
| 78 | * @param string $name |
||
| 79 | * @return bool |
||
| 80 | * @throws \Exception |
||
| 81 | * @internal |
||
| 82 | */ |
||
| 83 | function __isset($name) { |
||
| 92 | } |
||
| 93 | } |
||
| 94 | |||
| 95 | /** |
||
| 96 | * @param string $name |
||
| 97 | * @return mixed |
||
| 98 | * @throws \RuntimeException |
||
| 99 | * @internal |
||
| 100 | */ |
||
| 101 | function __get($name) { |
||
| 102 | if(\property_exists($this, $name)) { |
||
| 103 | return $this->$name; |
||
| 104 | } |
||
| 105 | |||
| 106 | return $this->message->$name; |
||
| 107 | } |
||
| 108 | |||
| 109 | /** |
||
| 110 | * @return mixed |
||
| 111 | * @throws \RuntimeException |
||
| 112 | * @internal |
||
| 113 | */ |
||
| 114 | function __call($name, $args) { |
||
| 120 | } |
||
| 121 | |||
| 122 | /** |
||
| 123 | * @return string |
||
| 124 | * @internal |
||
| 125 | */ |
||
| 126 | function serialize() { |
||
| 127 | $cmd = $this->command; |
||
| 128 | $this->command = null; |
||
| 129 | |||
| 130 | if($cmd !== null) { |
||
| 131 | $this->internalCommand = $cmd->groupID.':'.$cmd->name; |
||
| 132 | } |
||
| 133 | |||
| 134 | $str = parent::serialize(); |
||
| 135 | $this->command = $cmd; |
||
| 136 | |||
| 137 | return $str; |
||
| 138 | } |
||
| 139 | |||
| 140 | /** |
||
| 141 | * @return void |
||
| 142 | * @internal |
||
| 143 | */ |
||
| 144 | function unserialize($data) { |
||
| 145 | if(self::$serializeClient === null) { |
||
| 146 | throw new \Exception('Unable to unserialize a class without ClientBase::$serializeClient being set'); |
||
| 147 | } |
||
| 148 | |||
| 149 | parent::unserialize($data); |
||
| 150 | |||
| 151 | /** @var \CharlotteDunois\Livia\LiviaClient $this->client */ |
||
| 152 | $this->client = self::$serializeClient; |
||
| 153 | |||
| 154 | if($this->internalCommand !== null) { |
||
| 155 | $this->command = $this->client->registry->resolveCommand($this->internalCommand); |
||
| 156 | $this->internalCommand = null; |
||
| 157 | } |
||
| 158 | } |
||
| 159 | |||
| 160 | /** |
||
| 161 | * Parses the argString into usable arguments, based on the argsType and argsCount of the command. |
||
| 162 | * @return string|string[] |
||
| 163 | * @throws \LogicException |
||
| 164 | * @throws \RangeException |
||
| 165 | */ |
||
| 166 | function parseCommandArgs() { |
||
| 179 | } |
||
| 180 | } |
||
| 181 | |||
| 182 | /** |
||
| 183 | * Runs the command. Resolves with an instance of Message or an array of Message instances. |
||
| 184 | * @return \React\Promise\ExtendedPromiseInterface |
||
| 185 | * @throws \LogicException |
||
| 186 | */ |
||
| 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 | })); |
||
| 392 | } |
||
| 393 | |||
| 394 | /** |
||
| 395 | * Responds to the command message |
||
| 396 | * @param string $type One of plain, reply or direct. |
||
| 397 | * @param string $content |
||
| 398 | * @param array $options |
||
| 399 | * @param bool $fromEdit |
||
| 400 | * @return \React\Promise\ExtendedPromiseInterface |
||
| 401 | * @throws \RangeException |
||
| 402 | * @throws \InvalidArgumentException |
||
| 403 | */ |
||
| 404 | protected function respond(string $type, string $content, array $options = array(), bool $fromEdit = false) { |
||
| 405 | if($type === 'reply' && $this->message->channel instanceof \CharlotteDunois\Yasmin\Interfaces\DMChannelInterface) { |
||
| 406 | $type = 'plain'; |
||
| 407 | } |
||
| 408 | |||
| 409 | if($type !== 'direct' && $this->message->guild !== null && !$this->message->channel->permissionsFor($this->client->user)->has('SEND_MESSAGES')) { |
||
| 410 | $type = 'direct'; |
||
| 411 | } |
||
| 412 | |||
| 413 | if(!empty($options['split']) && !\is_array($options['split'])) { |
||
| 414 | $options['split'] = array(); |
||
| 415 | } |
||
| 416 | |||
| 417 | $channelID = $this->getChannelIDOrDM($this->message->channel); |
||
| 418 | $shouldEdit = ( |
||
| 419 | !empty($this->responses) && |
||
| 420 | ( |
||
| 421 | ($type === 'direct' && !empty($this->responses['dm'])) || |
||
| 422 | ($type !== 'direct' && !empty($this->responses[$channelID])) |
||
| 423 | ) && |
||
| 424 | !$fromEdit && |
||
| 425 | empty($options['files']) |
||
| 426 | ); |
||
| 427 | |||
| 428 | switch($type) { |
||
| 429 | case 'plain': |
||
| 430 | if($shouldEdit) { |
||
| 431 | return $this->editCurrentResponse($channelID, $type, $content, $options); |
||
| 432 | } else { |
||
| 433 | return $this->message->channel->send($content, $options); |
||
| 434 | } |
||
| 435 | break; |
||
| 436 | case 'reply': |
||
| 437 | if($shouldEdit) { |
||
| 438 | return $this->editCurrentResponse($channelID, $type, $content, $options); |
||
| 439 | } else { |
||
| 440 | if(!empty($options['split']) && empty($options['split']['prepend'])) { |
||
| 441 | $options['split']['prepend'] = $this->message->author->__toString().\CharlotteDunois\Yasmin\Models\Message::$replySeparator; |
||
| 442 | } |
||
| 443 | |||
| 444 | return $this->message->reply($content, $options); |
||
| 445 | } |
||
| 446 | break; |
||
| 447 | case 'direct': |
||
| 448 | if($shouldEdit) { |
||
| 449 | return $this->editCurrentResponse($channelID, $type, $content, $options); |
||
| 450 | } else { |
||
| 451 | return $this->message->author->createDM()->then(function ($channel) use ($content, $options) { |
||
| 452 | return $channel->send($content, $options); |
||
| 453 | }); |
||
| 454 | } |
||
| 455 | break; |
||
| 456 | default: |
||
| 457 | throw new \RangeException('Unknown response type "'.$type.'"'); |
||
| 458 | break; |
||
| 459 | } |
||
| 460 | } |
||
| 461 | |||
| 462 | /** |
||
| 463 | * Edits a response to the command message. Resolves with an instance of Message or an array of Message instances. |
||
| 464 | * @param \CharlotteDunois\Yasmin\Models\Message|\CharlotteDunois\Yasmin\Models\Message[]|null $response |
||
| 465 | * @param string $type |
||
| 466 | * @param string $content |
||
| 467 | * @param array $options |
||
| 468 | * @return \React\Promise\ExtendedPromiseInterface |
||
| 469 | */ |
||
| 470 | protected function editResponse($response, string $type, string $content, array $options = array()) { |
||
| 471 | if(!$response) { |
||
| 472 | return $this->respond($type, $content, $options); |
||
| 473 | } |
||
| 474 | |||
| 475 | if(!empty($options['split'])) { |
||
| 476 | $content = \CharlotteDunois\Yasmin\Utils\MessageHelpers::splitMessage($content, (\is_array($options['split']) ? $options['split'] : array())); |
||
| 477 | if(\count($content) === 1) { |
||
| 478 | $content = $content[0]; |
||
| 479 | } |
||
| 480 | } |
||
| 481 | |||
| 482 | $prepend = ''; |
||
| 483 | if($type === 'reply') { |
||
| 484 | $prepend = $this->message->author->__toString().\CharlotteDunois\Yasmin\Models\Message::$replySeparator; |
||
| 485 | } |
||
| 486 | |||
| 487 | if(\is_array($content)) { |
||
| 488 | $promises = array(); |
||
| 489 | $clength = \count($content); |
||
| 490 | |||
| 491 | if(\is_array($response)) { |
||
| 492 | for($i = 0; $i < $clength; $i++) { |
||
| 493 | if(!empty($response[$i])) { |
||
| 494 | $promises[] = $response[$i]->edit($prepend.$content[$i], $options); |
||
| 495 | } else { |
||
| 496 | $promises[] = $this->message->channel->send($prepend.$content[$i], $options); |
||
| 497 | } |
||
| 498 | } |
||
| 499 | } else { |
||
| 500 | $promises[] = $response->edit($prepend.$content[0], $options); |
||
| 501 | for($i = 1; $i < $clength; $i++) { |
||
| 502 | $promises[] = $this->message->channel->send($prepend.$content[$i], $options); |
||
| 503 | } |
||
| 504 | } |
||
| 505 | |||
| 506 | return \React\Promise\all($promises); |
||
| 507 | } else { |
||
| 508 | if(\is_array($response)) { |
||
| 509 | for($i = \count($response) - 1; $i > 0; $i--) { |
||
| 510 | $response[$i]->delete()->done(); |
||
| 511 | } |
||
| 512 | |||
| 513 | return $response[0]->edit($prepend.$content, $options); |
||
| 514 | } else { |
||
| 515 | return $response->edit($prepend.$content, $options); |
||
| 516 | } |
||
| 517 | } |
||
| 518 | } |
||
| 519 | |||
| 520 | /** |
||
| 521 | * Edits the current response. |
||
| 522 | * @param string $id The ID of the channel the response is in ("DM" for direct messages). |
||
| 523 | * @param string $type |
||
| 524 | * @param string $content |
||
| 525 | * @param array $options |
||
| 526 | * @return \React\Promise\ExtendedPromiseInterface |
||
| 527 | */ |
||
| 528 | protected function editCurrentResponse(string $id, string $type, string $content, array $options = array()) { |
||
| 529 | if(empty($this->responses[$id])) { |
||
| 530 | $this->responses[$id] = array(); |
||
| 531 | } |
||
| 532 | |||
| 533 | if(!empty($this->responses[$id])) { |
||
| 534 | $msg = \array_shift($this->responses[$id]); |
||
| 535 | } else { |
||
| 536 | $msg = null; |
||
| 537 | } |
||
| 538 | |||
| 539 | return $this->editResponse($msg, $type, $content, $options); |
||
| 540 | } |
||
| 541 | |||
| 542 | /** |
||
| 543 | * Responds with a plain message. Resolves with an instance of Message or an array of Message instances. |
||
| 544 | * @param string $content |
||
| 545 | * @param array $options Message Options. |
||
| 546 | * @return \React\Promise\ExtendedPromiseInterface |
||
| 547 | */ |
||
| 548 | function say(string $content, array $options = array()) { |
||
| 549 | return $this->respond('plain', $content, $options); |
||
| 550 | } |
||
| 551 | |||
| 552 | /** |
||
| 553 | * Responds with a reply message. Resolves with an instance of Message or an array of Message instances. |
||
| 554 | * @param string $content |
||
| 555 | * @param array $options Message Options. |
||
| 556 | * @return \React\Promise\ExtendedPromiseInterface |
||
| 557 | */ |
||
| 558 | function reply(string $content, array $options = array()) { |
||
| 559 | return $this->respond('reply', $content, $options); |
||
| 560 | } |
||
| 561 | |||
| 562 | /** |
||
| 563 | * Responds with a direct message. Resolves with an instance of Message or an array of Message instances. |
||
| 564 | * @param string $content |
||
| 565 | * @param array $options Message Options. |
||
| 566 | * @return \React\Promise\ExtendedPromiseInterface |
||
| 567 | */ |
||
| 568 | function direct(string $content, array $options = array()) { |
||
| 569 | return $this->respond('direct', $content, $options); |
||
| 570 | } |
||
| 571 | |||
| 572 | /** |
||
| 573 | * Shortcut to $this->message->edit. |
||
| 574 | * @param string $content |
||
| 575 | * @param array $options Message Options. |
||
| 576 | * @return \React\Promise\ExtendedPromiseInterface |
||
| 577 | */ |
||
| 578 | function edit(string $content, array $options = array()) { |
||
| 579 | return $this->message->edit($content, $options); |
||
| 580 | } |
||
| 581 | |||
| 582 | /** |
||
| 583 | * Finalizes the command message by setting the responses and deleting any remaining prior ones. |
||
| 584 | * @param \CharlotteDunois\Yasmin\Models\Message|\CharlotteDunois\Yasmin\Models\Message[]|null $responses |
||
| 585 | * @return void |
||
| 586 | * @internal |
||
| 587 | */ |
||
| 588 | function finalize($responses) { |
||
| 617 | } |
||
| 618 | } |
||
| 619 | |||
| 620 | /** |
||
| 621 | * Deletes any prior responses that haven't been updated. |
||
| 622 | * @return void |
||
| 623 | * @internal |
||
| 624 | */ |
||
| 625 | function deleteRemainingResponses() { |
||
| 626 | foreach($this->responses as $id => $msgs) { |
||
| 627 | foreach($msgs as $response) { |
||
| 628 | if(\is_array($response)) { |
||
| 629 | foreach($response as $resp) { |
||
| 630 | $resp->delete()->done(); |
||
| 631 | } |
||
| 632 | } else { |
||
| 633 | $response->delete()->done(); |
||
| 634 | } |
||
| 635 | } |
||
| 636 | |||
| 637 | $this->responses[$id] = array(); |
||
| 638 | } |
||
| 639 | } |
||
| 640 | |||
| 641 | /** |
||
| 642 | * @return string|int |
||
| 643 | */ |
||
| 644 | protected function getChannelIDOrDM(\CharlotteDunois\Yasmin\Interfaces\TextChannelInterface $channel) { |
||
| 645 | if(!($channel instanceof \CharlotteDunois\Yasmin\Interfaces\DMChannelInterface)) { |
||
| 646 | return $channel->id; |
||
| 647 | } |
||
| 648 | |||
| 649 | return 'dm'; |
||
| 650 | } |
||
| 651 | |||
| 652 | /** |
||
| 653 | * Parses an argument string into an array of arguments. |
||
| 654 | * @param string $argString |
||
| 655 | * @param int|float|null $argCount float = \INF |
||
| 656 | * @param bool $allowSingleQuotes |
||
| 657 | * @return string[] |
||
| 658 | */ |
||
| 659 | static function parseArgs(string $argString, $argCount = null, bool $allowSingleQuotes = true) { |
||
| 704 | } |
||
| 705 | |||
| 706 | /** |
||
| 707 | * @return void |
||
| 708 | * @internal |
||
| 709 | */ |
||
| 710 | function setResponses($responses) { |
||
| 711 | $this->responses = $responses; |
||
| 712 | } |
||
| 713 | } |
||
| 714 |