command) { case 'presence': return new PresenceCommand($discord, $cmd); case 'result': return new ResultCommand($discord, $cmd); case 'sync-user': return new SyncUserCommand($discord, $cmd); default: throw new Exception('unrecognized command'); } } public abstract function execute(); protected function __construct(Discord $discord, DiscordBotCommand $cmd) { $this->discord = $discord; $this->command = $cmd; if ($cmd->tournament && $cmd->tournament->locale) { App::setLocale($cmd->tournament->locale); } } protected function fetchGuild() { if (isset($this->guild)) { return \React\Promise\resolve($this->guild); } return $this->discord->guilds ->fetch($this->command->tournament->discord) ->then(function (Guild $guild) { $this->guild = $guild; if ($guild->preferred_locale && !($this->command->tournament && $this->command->tournament->locale)) { App::setLocale($guild->preferred_locale); } return $guild; }); } protected function fetchMember() { return $this->fetchGuild()->then(function (Guild $guild) { return $guild->members ->fetch($this->getParameter('user')) ->then(function (Member $member) { $this->member = $member; return $member; }); }); } protected function fetchRoundChannel() { if (isset($this->roundChannel)) { return \React\Promise\resolve($this->roundChannel); } return $this->fetchGuild() ->then(function (Guild $guild) { $channel = $guild->channels->find(function (Channel $c) { return $c->name == $this->getRoundChannelName(); }); if ($channel) { return $channel; } $channel = $guild->channels->create([ 'name' => $this->getRoundChannelName(), 'is_private' => true, 'parent_id' => $this->command->tournament->discord_round_category, ]); return $guild->channels->save($channel); }) ->then(function (Channel $channel) { $this->roundChannel = $channel; return $channel; }); } protected function fetchUser() { if (isset($this->user)) { return \React\Promise\resolve($this->user); } return $this->discord->users ->fetch($this->getParameter('user')) ->then(function (DiscordUser $user) { $this->user = $user; return $user; }); } protected function getParameter($name) { return $this->command->parameters[$name]; } protected function getRound() { if (!$this->hasParameter('round')) { throw new \Exception('no rounds in parameters'); } return Round::findOrFail($this->getParameter('round')); } protected function getRoundChannelName() { $round = $this->getRound(); return sprintf($this->command->tournament->discord_round_template, $round->number); } protected function getUser() { if (!$this->hasParameter('user')) { throw new \Exception('no user in parameters'); } return User::findOrFail($this->getParameter('user')); } protected function hasParameter($name) { return array_key_exists($name, $this->command->parameters); } protected function hasRoundChannels() { return !empty($this->command->tournament->discord_round_template); } protected $command; protected $discord; protected $guild = null; protected $member = null; protected $roundChannel = null; protected $user = null; }