#116 - cr fix
This commit is contained in:
		
							
								
								
									
										36
									
								
								app/Infrastructure/Slack/Channels/SlackApiChannel.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								app/Infrastructure/Slack/Channels/SlackApiChannel.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,36 @@ | ||||
| <?php | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace Toby\Infrastructure\Slack\Channels; | ||||
|  | ||||
| use Illuminate\Http\Client\Response; | ||||
| use Illuminate\Notifications\Notification; | ||||
| use Illuminate\Support\Facades\Http; | ||||
| use Toby\Domain\Notifications\Notifiable; | ||||
|  | ||||
| class SlackApiChannel | ||||
| { | ||||
|     public function send(Notifiable $notifiable, Notification $notification): Response | ||||
|     { | ||||
|         $baseUrl = $this->getBaseUrl(); | ||||
|         $url = "{$baseUrl}/chat.postMessage"; | ||||
|         $channel = $notifiable->routeNotificationFor("slack", $notification); | ||||
|  | ||||
|         return Http::withToken($this->getClientToken()) | ||||
|             ->post($url, [ | ||||
|                 "channel" => $channel, | ||||
|                 "text" => $notification->toSlack($notifiable), | ||||
|             ]); | ||||
|     } | ||||
|  | ||||
|     protected function getClientToken(): string | ||||
|     { | ||||
|         return config("services.slack.client_token"); | ||||
|     } | ||||
|  | ||||
|     protected function getBaseUrl(): string | ||||
|     { | ||||
|         return config("services.slack.url"); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										56
									
								
								app/Infrastructure/Slack/Controller.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								app/Infrastructure/Slack/Controller.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,56 @@ | ||||
| <?php | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace Toby\Infrastructure\Slack; | ||||
|  | ||||
| use Exception; | ||||
| use Illuminate\Http\Request as IlluminateRequest; | ||||
| use Illuminate\Http\Response as IlluminateResponse; | ||||
| use Illuminate\Support\Collection; | ||||
| use Illuminate\Validation\ValidationException; | ||||
| use Spatie\SlashCommand\Attachment; | ||||
| use Spatie\SlashCommand\Controller as SlackController; | ||||
| use Spatie\SlashCommand\Exceptions\InvalidRequest; | ||||
| use Spatie\SlashCommand\Exceptions\RequestCouldNotBeHandled; | ||||
| use Spatie\SlashCommand\Exceptions\SlackSlashCommandException; | ||||
| use Spatie\SlashCommand\Response; | ||||
|  | ||||
| class Controller extends SlackController | ||||
| { | ||||
|     /** | ||||
|      * @throws InvalidRequest|RequestCouldNotBeHandled | ||||
|      */ | ||||
|     public function getResponse(IlluminateRequest $request): IlluminateResponse | ||||
|     { | ||||
|         $this->verifyWithSigning($request); | ||||
|  | ||||
|         $handler = $this->determineHandler(); | ||||
|  | ||||
|         try { | ||||
|             $response = $handler->handle($this->request); | ||||
|         } catch (SlackSlashCommandException $exception) { | ||||
|             $response = $exception->getResponse($this->request); | ||||
|         } catch (ValidationException $exception) { | ||||
|             $response = $this->prepareValidationResponse($exception); | ||||
|         } catch (Exception $exception) { | ||||
|             $response = $this->convertToResponse($exception); | ||||
|         } | ||||
|  | ||||
|         return $response->getIlluminateResponse(); | ||||
|     } | ||||
|  | ||||
|     protected function prepareValidationResponse(ValidationException $exception): Response | ||||
|     { | ||||
|         $errors = (new Collection($exception->errors())) | ||||
|             ->map( | ||||
|                 fn(array $message): Attachment => Attachment::create() | ||||
|                     ->setColor("danger") | ||||
|                     ->setText($message[0]), | ||||
|             ); | ||||
|  | ||||
|         return Response::create($this->request) | ||||
|             ->withText(":x: Polecenie `/{$this->request->command} {$this->request->text}` jest niepoprawna:") | ||||
|             ->withAttachments($errors->all()); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										22
									
								
								app/Infrastructure/Slack/Elements/AbsencesAttachment.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								app/Infrastructure/Slack/Elements/AbsencesAttachment.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,22 @@ | ||||
| <?php | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace Toby\Infrastructure\Slack\Elements; | ||||
|  | ||||
| use Illuminate\Support\Collection; | ||||
| use Toby\Eloquent\Models\Vacation; | ||||
|  | ||||
| class AbsencesAttachment extends ListAttachment | ||||
| { | ||||
|     public function __construct(Collection $absences) | ||||
|     { | ||||
|         parent::__construct(); | ||||
|  | ||||
|         $this | ||||
|             ->setTitle("Nieobecności :palm_tree:") | ||||
|             ->setColor("#eab308") | ||||
|             ->setItems($absences->map(fn(Vacation $vacation): string => $vacation->user->profile->full_name)) | ||||
|             ->setEmptyText("Wszyscy dzisiaj pracują :muscle:"); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										12
									
								
								app/Infrastructure/Slack/Elements/Attachment.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								app/Infrastructure/Slack/Elements/Attachment.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | ||||
| <?php | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace Toby\Infrastructure\Slack\Elements; | ||||
|  | ||||
| use Illuminate\Contracts\Support\Arrayable; | ||||
| use Spatie\SlashCommand\Attachment as BaseAttachment; | ||||
|  | ||||
| class Attachment extends BaseAttachment implements Arrayable | ||||
| { | ||||
| } | ||||
							
								
								
									
										22
									
								
								app/Infrastructure/Slack/Elements/BirthdaysAttachment.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								app/Infrastructure/Slack/Elements/BirthdaysAttachment.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,22 @@ | ||||
| <?php | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace Toby\Infrastructure\Slack\Elements; | ||||
|  | ||||
| use Illuminate\Support\Collection; | ||||
| use Toby\Eloquent\Models\User; | ||||
|  | ||||
| class BirthdaysAttachment extends ListAttachment | ||||
| { | ||||
|     public function __construct(Collection $birthdays) | ||||
|     { | ||||
|         parent::__construct(); | ||||
|  | ||||
|         $this | ||||
|             ->setTitle("Urodziny :birthday:") | ||||
|             ->setColor("#3c5f97") | ||||
|             ->setItems($birthdays->map(fn(User $user): string => $user->profile->full_name)) | ||||
|             ->setEmptyText("Dzisiaj nikt nie ma urodzin :cry:"); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										21
									
								
								app/Infrastructure/Slack/Elements/KeysAttachment.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								app/Infrastructure/Slack/Elements/KeysAttachment.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,21 @@ | ||||
| <?php | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace Toby\Infrastructure\Slack\Elements; | ||||
|  | ||||
| use Illuminate\Support\Collection; | ||||
| use Toby\Eloquent\Models\Key; | ||||
|  | ||||
| class KeysAttachment extends ListAttachment | ||||
| { | ||||
|     public function __construct(Collection $keys) | ||||
|     { | ||||
|         parent::__construct(); | ||||
|  | ||||
|         $this | ||||
|             ->setColor("#3c5f97") | ||||
|             ->setItems($keys->map(fn(Key $key): string => "Klucz nr {$key->id} - <@{$key->user->profile->slack_id}>")) | ||||
|             ->setEmptyText("Nie ma żadnych kluczy w tobym"); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										36
									
								
								app/Infrastructure/Slack/Elements/ListAttachment.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								app/Infrastructure/Slack/Elements/ListAttachment.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,36 @@ | ||||
| <?php | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace Toby\Infrastructure\Slack\Elements; | ||||
|  | ||||
| use Illuminate\Support\Collection; | ||||
|  | ||||
| class ListAttachment extends Attachment | ||||
| { | ||||
|     protected Collection $items; | ||||
|     protected string $emptyText = ""; | ||||
|  | ||||
|     public function setItems(Collection $items): static | ||||
|     { | ||||
|         $this->items = $items; | ||||
|  | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     public function setEmptyText(string $emptyText): static | ||||
|     { | ||||
|         $this->emptyText = $emptyText; | ||||
|  | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     public function toArray(): array | ||||
|     { | ||||
|         $fields = parent::toArray(); | ||||
|  | ||||
|         return array_merge($fields, [ | ||||
|             "text" => $this->items->isNotEmpty() ? $this->items->implode("\n") : $this->emptyText, | ||||
|         ]); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										22
									
								
								app/Infrastructure/Slack/Elements/RemotesAttachment.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								app/Infrastructure/Slack/Elements/RemotesAttachment.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,22 @@ | ||||
| <?php | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace Toby\Infrastructure\Slack\Elements; | ||||
|  | ||||
| use Illuminate\Support\Collection; | ||||
| use Toby\Eloquent\Models\Vacation; | ||||
|  | ||||
| class RemotesAttachment extends ListAttachment | ||||
| { | ||||
|     public function __construct(Collection $remoteDays) | ||||
|     { | ||||
|         parent::__construct(); | ||||
|  | ||||
|         $this | ||||
|             ->setTitle("Praca zdalna :house_with_garden:") | ||||
|             ->setColor("#527aba") | ||||
|             ->setItems($remoteDays->map(fn(Vacation $vacation): string => $vacation->user->profile->full_name)) | ||||
|             ->setEmptyText("Wszyscy dzisiaj są w biurze :boom:"); | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,11 @@ | ||||
| <?php | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace Toby\Infrastructure\Slack\Exceptions; | ||||
|  | ||||
| use Spatie\SlashCommand\Exceptions\SlackSlashCommandException; | ||||
|  | ||||
| class UserNotFoundException extends SlackSlashCommandException | ||||
| { | ||||
| } | ||||
							
								
								
									
										35
									
								
								app/Infrastructure/Slack/Handlers/CatchAll.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								app/Infrastructure/Slack/Handlers/CatchAll.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,35 @@ | ||||
| <?php | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace Toby\Infrastructure\Slack\Handlers; | ||||
|  | ||||
| use Spatie\SlashCommand\Handlers\BaseHandler; | ||||
| use Spatie\SlashCommand\Request; | ||||
| use Spatie\SlashCommand\Response; | ||||
| use Toby\Infrastructure\Slack\Elements\Attachment; | ||||
| use Toby\Infrastructure\Slack\Traits\ListsHandlers; | ||||
|  | ||||
| class CatchAll extends BaseHandler | ||||
| { | ||||
|     use ListsHandlers; | ||||
|  | ||||
|     public function canHandle(Request $request): bool | ||||
|     { | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     public function handle(Request $request): Response | ||||
|     { | ||||
|         $handlers = $this->findAvailableHandlers(); | ||||
|         $attachmentFields = $this->mapHandlersToAttachments($handlers); | ||||
|  | ||||
|         return $this->respondToSlack(":x: Nie rozpoznaję polecenia. Lista wszystkich poleceń:") | ||||
|             ->withAttachment( | ||||
|                 Attachment::create() | ||||
|                     ->setColor("danger") | ||||
|                     ->useMarkdown() | ||||
|                     ->setFields($attachmentFields), | ||||
|             ); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										36
									
								
								app/Infrastructure/Slack/Handlers/DailySummary.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								app/Infrastructure/Slack/Handlers/DailySummary.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,36 @@ | ||||
| <?php | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace Toby\Infrastructure\Slack\Handlers; | ||||
|  | ||||
| use Illuminate\Support\Carbon; | ||||
| use Illuminate\Support\Collection; | ||||
| use Spatie\SlashCommand\Request; | ||||
| use Spatie\SlashCommand\Response; | ||||
| use Toby\Domain\DailySummaryRetriever; | ||||
| use Toby\Infrastructure\Slack\Elements\AbsencesAttachment; | ||||
| use Toby\Infrastructure\Slack\Elements\BirthdaysAttachment; | ||||
| use Toby\Infrastructure\Slack\Elements\RemotesAttachment; | ||||
|  | ||||
| class DailySummary extends SignatureHandler | ||||
| { | ||||
|     protected $signature = "toby dzisiaj"; | ||||
|     protected $description = "Codzienne podsumowanie"; | ||||
|  | ||||
|     public function handle(Request $request): Response | ||||
|     { | ||||
|         $dailySummaryRetriever = app()->make(DailySummaryRetriever::class); | ||||
|  | ||||
|         $now = Carbon::today(); | ||||
|  | ||||
|         $attachments = new Collection([ | ||||
|             new AbsencesAttachment($dailySummaryRetriever->getAbsences($now)), | ||||
|             new RemotesAttachment($dailySummaryRetriever->getRemoteDays($now)), | ||||
|             new BirthdaysAttachment($dailySummaryRetriever->getBirthdays($now)), | ||||
|         ]); | ||||
|  | ||||
|         return $this->respondToSlack("Podsumowanie dla dnia {$now->toDisplayString()}") | ||||
|             ->withAttachments($attachments->all()); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										71
									
								
								app/Infrastructure/Slack/Handlers/GiveKeysTo.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								app/Infrastructure/Slack/Handlers/GiveKeysTo.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,71 @@ | ||||
| <?php | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace Toby\Infrastructure\Slack\Handlers; | ||||
|  | ||||
| use Illuminate\Validation\ValidationException; | ||||
| use Spatie\SlashCommand\Request; | ||||
| use Spatie\SlashCommand\Response; | ||||
| use Toby\Domain\Notifications\KeyHasBeenGivenNotification; | ||||
| use Toby\Eloquent\Models\Key; | ||||
| use Toby\Infrastructure\Slack\Exceptions\UserNotFoundException; | ||||
| use Toby\Infrastructure\Slack\Rules\SlackUserExistsRule; | ||||
| use Toby\Infrastructure\Slack\Traits\FindsUserBySlackId; | ||||
|  | ||||
| class GiveKeysTo extends SignatureHandler | ||||
| { | ||||
|     use FindsUserBySlackId; | ||||
|  | ||||
|     protected $signature = "toby klucze:dla {user}"; | ||||
|     protected $description = "Przekaż klucze wskazanemu użytkownikowi"; | ||||
|  | ||||
|     /** | ||||
|      * @throws UserNotFoundException | ||||
|      * @throws ValidationException | ||||
|      */ | ||||
|     public function handle(Request $request): Response | ||||
|     { | ||||
|         ["user" => $from] = $this->validate(); | ||||
|  | ||||
|         $authUser = $this->findUserBySlackIdOrFail($request->userId); | ||||
|         $user = $this->findUserBySlackId($from); | ||||
|  | ||||
|         /** @var Key $key */ | ||||
|         $key = $authUser->keys()->first(); | ||||
|  | ||||
|         if (!$key) { | ||||
|             throw ValidationException::withMessages(["key" => "Nie masz żadnego klucza do przekazania"]); | ||||
|         } | ||||
|  | ||||
|         if ($user->is($authUser)) { | ||||
|             throw ValidationException::withMessages([ | ||||
|                 "key" => "Nie możesz przekazać sobie kluczy :dzban:", | ||||
|             ]); | ||||
|         } | ||||
|  | ||||
|         $key->user()->associate($user); | ||||
|  | ||||
|         $key->save(); | ||||
|  | ||||
|         $key->notify(new KeyHasBeenGivenNotification($authUser, $user)); | ||||
|  | ||||
|         return $this->respondToSlack( | ||||
|             ":white_check_mark: Klucz nr {$key->id} został przekazany użytkownikowi <@{$user->profile->slack_id}>", | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|     protected function getRules(): array | ||||
|     { | ||||
|         return [ | ||||
|             "user" => ["required", new SlackUserExistsRule()], | ||||
|         ]; | ||||
|     } | ||||
|  | ||||
|     protected function getMessages(): array | ||||
|     { | ||||
|         return [ | ||||
|             "user.required" => "Musisz podać użytkownika, któremu chcesz przekazać klucze", | ||||
|         ]; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										33
									
								
								app/Infrastructure/Slack/Handlers/Help.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								app/Infrastructure/Slack/Handlers/Help.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,33 @@ | ||||
| <?php | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace Toby\Infrastructure\Slack\Handlers; | ||||
|  | ||||
| use Spatie\SlashCommand\Request; | ||||
| use Spatie\SlashCommand\Response; | ||||
| use Toby\Infrastructure\Slack\Elements\Attachment; | ||||
| use Toby\Infrastructure\Slack\Traits\ListsHandlers; | ||||
|  | ||||
| class Help extends SignatureHandler | ||||
| { | ||||
|     use ListsHandlers; | ||||
|  | ||||
|     protected $signature = "toby pomoc"; | ||||
|     protected $description = "Wyświetl wszystkie dostępne polecenia"; | ||||
|  | ||||
|     public function handle(Request $request): Response | ||||
|     { | ||||
|         $handlers = $this->findAvailableHandlers(); | ||||
|  | ||||
|         $attachmentFields = $this->mapHandlersToAttachments($handlers); | ||||
|  | ||||
|         return $this->respondToSlack("Dostępne polecenia:") | ||||
|             ->withAttachment( | ||||
|                 Attachment::create() | ||||
|                     ->setColor("good") | ||||
|                     ->useMarkdown() | ||||
|                     ->setFields($attachmentFields), | ||||
|             ); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										45
									
								
								app/Infrastructure/Slack/Handlers/HomeOffice.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								app/Infrastructure/Slack/Handlers/HomeOffice.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,45 @@ | ||||
| <?php | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace Toby\Infrastructure\Slack\Handlers; | ||||
|  | ||||
| use Illuminate\Support\Carbon; | ||||
| use Spatie\SlashCommand\Request; | ||||
| use Spatie\SlashCommand\Response; | ||||
| use Toby\Domain\Actions\VacationRequest\CreateAction; | ||||
| use Toby\Domain\Enums\VacationType; | ||||
| use Toby\Eloquent\Models\User; | ||||
| use Toby\Eloquent\Models\YearPeriod; | ||||
| use Toby\Infrastructure\Slack\Traits\FindsUserBySlackId; | ||||
|  | ||||
| class HomeOffice extends SignatureHandler | ||||
| { | ||||
|     use FindsUserBySlackId; | ||||
|  | ||||
|     protected $signature = "toby zdalnie"; | ||||
|     protected $description = "Pracuj dzisiaj zdalnie"; | ||||
|  | ||||
|     public function handle(Request $request): Response | ||||
|     { | ||||
|         $user = $this->findUserBySlackId($request->userId); | ||||
|  | ||||
|         $this->createRemoteday($user, Carbon::today()); | ||||
|  | ||||
|         return $this->respondToSlack(":white_check_mark: Pracujesz dzisiaj zdalnie"); | ||||
|     } | ||||
|  | ||||
|     protected function createRemoteday(User $user, Carbon $date): void | ||||
|     { | ||||
|         $yearPeriod = YearPeriod::findByYear($date->year); | ||||
|  | ||||
|         app(CreateAction::class)->execute([ | ||||
|             "user_id" => $user->id, | ||||
|             "type" => VacationType::HomeOffice, | ||||
|             "from" => $date, | ||||
|             "to" => $date, | ||||
|             "year_period_id" => $yearPeriod->id, | ||||
|             "flow_skipped" => false, | ||||
|         ], $user); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										26
									
								
								app/Infrastructure/Slack/Handlers/KeyList.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								app/Infrastructure/Slack/Handlers/KeyList.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,26 @@ | ||||
| <?php | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace Toby\Infrastructure\Slack\Handlers; | ||||
|  | ||||
| use Spatie\SlashCommand\Request; | ||||
| use Spatie\SlashCommand\Response; | ||||
| use Toby\Eloquent\Models\Key; | ||||
| use Toby\Infrastructure\Slack\Elements\KeysAttachment; | ||||
|  | ||||
| class KeyList extends SignatureHandler | ||||
| { | ||||
|     protected $signature = "toby klucze"; | ||||
|     protected $description = "Lista wszystkich kluczy"; | ||||
|  | ||||
|     public function handle(Request $request): Response | ||||
|     { | ||||
|         $keys = Key::query() | ||||
|             ->orderBy("id") | ||||
|             ->get(); | ||||
|  | ||||
|         return $this->respondToSlack("Lista kluczy :key:") | ||||
|             ->withAttachment(new KeysAttachment($keys)); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										26
									
								
								app/Infrastructure/Slack/Handlers/SignatureHandler.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								app/Infrastructure/Slack/Handlers/SignatureHandler.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,26 @@ | ||||
| <?php | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace Toby\Infrastructure\Slack\Handlers; | ||||
|  | ||||
| use Illuminate\Support\Facades\Validator; | ||||
| use Spatie\SlashCommand\Handlers\SignatureHandler as BaseSignatureHandler; | ||||
|  | ||||
| abstract class SignatureHandler extends BaseSignatureHandler | ||||
| { | ||||
|     public function validate() | ||||
|     { | ||||
|         return Validator::validate($this->getArguments(), $this->getRules(), $this->getMessages()); | ||||
|     } | ||||
|  | ||||
|     protected function getRules(): array | ||||
|     { | ||||
|         return []; | ||||
|     } | ||||
|  | ||||
|     protected function getMessages(): array | ||||
|     { | ||||
|         return []; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										70
									
								
								app/Infrastructure/Slack/Handlers/TakeKeysFrom.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								app/Infrastructure/Slack/Handlers/TakeKeysFrom.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,70 @@ | ||||
| <?php | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace Toby\Infrastructure\Slack\Handlers; | ||||
|  | ||||
| use Illuminate\Validation\ValidationException; | ||||
| use Spatie\SlashCommand\Request; | ||||
| use Spatie\SlashCommand\Response; | ||||
| use Toby\Domain\Notifications\KeyHasBeenTakenNotification; | ||||
| use Toby\Eloquent\Models\Key; | ||||
| use Toby\Infrastructure\Slack\Exceptions\UserNotFoundException; | ||||
| use Toby\Infrastructure\Slack\Rules\SlackUserExistsRule; | ||||
| use Toby\Infrastructure\Slack\Traits\FindsUserBySlackId; | ||||
|  | ||||
| class TakeKeysFrom extends SignatureHandler | ||||
| { | ||||
|     use FindsUserBySlackId; | ||||
|  | ||||
|     protected $signature = "toby klucze:od {user}"; | ||||
|     protected $description = "Zabierz klucze wskazanemu użytkownikowi"; | ||||
|  | ||||
|     /** | ||||
|      * @throws UserNotFoundException|ValidationException | ||||
|      */ | ||||
|     public function handle(Request $request): Response | ||||
|     { | ||||
|         ["user" => $from] = $this->validate(); | ||||
|  | ||||
|         $authUser = $this->findUserBySlackIdOrFail($request->userId); | ||||
|         $user = $this->findUserBySlackId($from); | ||||
|  | ||||
|         /** @var Key $key */ | ||||
|         $key = $user->keys()->first(); | ||||
|  | ||||
|         if (!$key) { | ||||
|             throw ValidationException::withMessages([ | ||||
|                 "key" => "Użytkownik <@{$user->profile->slack_id}> nie ma żadnych kluczy", | ||||
|             ]); | ||||
|         } | ||||
|  | ||||
|         if ($key->user()->is($authUser)) { | ||||
|             throw ValidationException::withMessages([ | ||||
|                 "key" => "Nie możesz zabrać sobie kluczy :dzban:", | ||||
|             ]); | ||||
|         } | ||||
|  | ||||
|         $key->user()->associate($authUser); | ||||
|  | ||||
|         $key->save(); | ||||
|  | ||||
|         $key->notify(new KeyHasBeenTakenNotification($authUser, $user)); | ||||
|  | ||||
|         return $this->respondToSlack(":white_check_mark: Klucz nr {$key->id} został zabrany użytkownikowi <@{$user->profile->slack_id}>"); | ||||
|     } | ||||
|  | ||||
|     protected function getRules(): array | ||||
|     { | ||||
|         return [ | ||||
|             "user" => ["required", new SlackUserExistsRule()], | ||||
|         ]; | ||||
|     } | ||||
|  | ||||
|     protected function getMessages(): array | ||||
|     { | ||||
|         return [ | ||||
|             "user.required" => "Musisz podać użytkownika, któremu chcesz zabrać klucze", | ||||
|         ]; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										24
									
								
								app/Infrastructure/Slack/Rules/SlackUserExistsRule.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								app/Infrastructure/Slack/Rules/SlackUserExistsRule.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,24 @@ | ||||
| <?php | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace Toby\Infrastructure\Slack\Rules; | ||||
|  | ||||
| use Illuminate\Contracts\Validation\Rule; | ||||
| use Illuminate\Support\Str; | ||||
| use Toby\Eloquent\Models\Profile; | ||||
|  | ||||
| class SlackUserExistsRule implements Rule | ||||
| { | ||||
|     public function passes($attribute, $value): bool | ||||
|     { | ||||
|         $slackId = Str::between($value, "<@", "|"); | ||||
|  | ||||
|         return Profile::query()->where("slack_id", $slackId)->exists(); | ||||
|     } | ||||
|  | ||||
|     public function message(): string | ||||
|     { | ||||
|         return "Użytkownik :input nie istnieje w tobym"; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										43
									
								
								app/Infrastructure/Slack/Traits/FindsUserBySlackId.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								app/Infrastructure/Slack/Traits/FindsUserBySlackId.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,43 @@ | ||||
| <?php | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace Toby\Infrastructure\Slack\Traits; | ||||
|  | ||||
| use Illuminate\Support\Str; | ||||
| use Toby\Eloquent\Models\User; | ||||
| use Toby\Infrastructure\Slack\Exceptions\UserNotFoundException; | ||||
|  | ||||
| trait FindsUserBySlackId | ||||
| { | ||||
|     protected function findUserBySlackId(string $slackId): ?User | ||||
|     { | ||||
|         $id = $this->prepareSlackIdFromString($slackId); | ||||
|  | ||||
|         /** @var User $user */ | ||||
|         $user = User::query() | ||||
|             ->whereRelation("profile", "slack_id", $id) | ||||
|             ->first(); | ||||
|  | ||||
|         return $user; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @throws UserNotFoundException | ||||
|      */ | ||||
|     protected function findUserBySlackIdOrFail(string $slackId): ?User | ||||
|     { | ||||
|         $user = $this->findUserBySlackId($slackId); | ||||
|  | ||||
|         if (!$user) { | ||||
|             throw new UserNotFoundException("Użytkownik {$slackId} nie istnieje w tobym"); | ||||
|         } | ||||
|  | ||||
|         return $user; | ||||
|     } | ||||
|  | ||||
|     protected function prepareSlackIdFromString(string $slackId): string | ||||
|     { | ||||
|         return Str::between($slackId, "<@", "|"); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										46
									
								
								app/Infrastructure/Slack/Traits/ListsHandlers.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								app/Infrastructure/Slack/Traits/ListsHandlers.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,46 @@ | ||||
| <?php | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace Toby\Infrastructure\Slack\Traits; | ||||
|  | ||||
| use Illuminate\Support\Collection; | ||||
| use Illuminate\Support\Str; | ||||
| use Spatie\SlashCommand\AttachmentField; | ||||
| use Spatie\SlashCommand\Handlers\BaseHandler; | ||||
| use Spatie\SlashCommand\Handlers\SignatureHandler; | ||||
| use Spatie\SlashCommand\Handlers\SignatureParts; | ||||
| use Spatie\SlashCommand\HandlesSlashCommand; | ||||
|  | ||||
| trait ListsHandlers | ||||
| { | ||||
|     protected function findAvailableHandlers(): Collection | ||||
|     { | ||||
|         return collect(config("laravel-slack-slash-command.handlers")) | ||||
|             ->map(fn(string $handlerClassName): BaseHandler => new $handlerClassName($this->request)) | ||||
|             ->filter(fn(HandlesSlashCommand $handler): bool => $handler instanceof SignatureHandler) | ||||
|             ->filter(function (SignatureHandler $handler) { | ||||
|                 $signatureParts = new SignatureParts($handler->getSignature()); | ||||
|  | ||||
|                 return Str::is($signatureParts->getSlashCommandName(), $this->request->command); | ||||
|             }); | ||||
|     } | ||||
|  | ||||
|     protected function mapHandlersToAttachments(Collection $handlers): array | ||||
|     { | ||||
|         return $handlers | ||||
|             ->sort( | ||||
|                 fn(SignatureHandler $handlerA, SignatureHandler $handlerB): int => strcmp( | ||||
|                     $handlerA->getFullCommand(), | ||||
|                     $handlerB->getFullCommand(), | ||||
|                 ), | ||||
|             ) | ||||
|             ->map( | ||||
|                 fn(SignatureHandler $handler): AttachmentField => AttachmentField::create( | ||||
|                     $handler->getDescription(), | ||||
|                     "`/{$handler->getSignature()}`", | ||||
|                 ), | ||||
|             ) | ||||
|             ->all(); | ||||
|     } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user