+<?php
+
+namespace App\DiscordBotCommands;
+
+use App\Models\DiscordBotCommand;
+use App\Models\Round;
+use App\Models\User;
+use Discord\Discord;
+use Discord\Parts\Channel\Channel;
+use Discord\Parts\Guild\Guild;
+use Discord\Parts\User\Member;
+use Illuminate\Support\Facades\App;
+
+abstract class BaseCommand {
+
+ public static function resolve(Discord $discord, DiscordBotCommand $cmd) {
+ switch ($cmd->command) {
+ case 'presence':
+ return new PresenceCommand($discord, $cmd);
+ case 'result':
+ return new ResultCommand($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;
+ }
+
+ 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) {
+ 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 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;
+
+}