diff --git a/app/Bootstrap/LoadConfiguration.php b/app/Bootstrap/LoadConfiguration.php index 76782c77..9f76daab 100644 --- a/app/Bootstrap/LoadConfiguration.php +++ b/app/Bootstrap/LoadConfiguration.php @@ -5,13 +5,11 @@ namespace App\Bootstrap; use Illuminate\Contracts\Config\Repository as RepositoryContract; use Illuminate\Contracts\Foundation\Application; -/** - * Class LoadConfiguration - */ class LoadConfiguration extends \Illuminate\Foundation\Bootstrap\LoadConfiguration { /** - * Load the configuration items from all of the files. + * Load the configuration items from all of the files. This reads the config.php from + * that's sitting in the root, and then recursively merges it with the current configs * * @param \Illuminate\Contracts\Foundation\Application $app * @param \Illuminate\Contracts\Config\Repository $repository diff --git a/app/Contracts/Award.php b/app/Contracts/Award.php index d30732c8..36c382e2 100644 --- a/app/Contracts/Award.php +++ b/app/Contracts/Award.php @@ -6,7 +6,8 @@ use App\Facades\Utils; use App\Models\Award as AwardModel; use App\Models\User; use App\Models\UserAward; -use Log; +use Exception; +use Illuminate\Support\Facades\Log; /** * Base class for the Awards, you need to extend this, and implement: @@ -38,12 +39,6 @@ abstract class Award protected $award; protected $user; - /** - * AwardInterface constructor. - * - * @param AwardModel $award - * @param User $user - */ public function __construct(AwardModel $award = null, User $user = null) { $this->award = $award; @@ -73,7 +68,7 @@ abstract class Award * * @return bool|UserAward */ - final protected function addAward() + protected function addAward() { $w = [ 'user_id' => $this->user->id, @@ -90,7 +85,7 @@ abstract class Award try { $award->save(); - } catch (\Exception $e) { + } catch (Exception $e) { Log::error( 'Error saving award: '.$e->getMessage(), $e->getTrace() diff --git a/app/Contracts/Listener.php b/app/Contracts/Listener.php index 7ce6f8a6..9245d044 100644 --- a/app/Contracts/Listener.php +++ b/app/Contracts/Listener.php @@ -2,9 +2,21 @@ namespace App\Contracts; -/** - * Class Listener - */ +use Illuminate\Contracts\Events\Dispatcher; + abstract class Listener { + public static $callbacks = []; + + /** + * Sets up any callbacks that are defined in the child class + * + * @param $events + */ + public function subscribe(Dispatcher $events): void + { + foreach (static::$callbacks as $klass => $cb) { + $events->listen($klass, get_class($this).'@'.$cb); + } + } } diff --git a/app/Database/seeds/dev/sample.yml b/app/Database/seeds/dev/sample.yml index 2edc9e58..6f6dcb50 100644 --- a/app/Database/seeds/dev/sample.yml +++ b/app/Database/seeds/dev/sample.yml @@ -20,7 +20,7 @@ awards: name: Pilot 50 flights description: When a pilot has 50 flights, give this award image_url: - ref_model: App\Awards\PilotFlightAwards + ref_model: Modules\Awards\Awards\PilotFlightAwards ref_model_params: 50 created_at: now updated_at: now diff --git a/app/Database/seeds/settings.yml b/app/Database/seeds/settings.yml index 9b58b44f..9ba00020 100644 --- a/app/Database/seeds/settings.yml +++ b/app/Database/seeds/settings.yml @@ -222,3 +222,17 @@ options: '' type: boolean description: 'Count transfer hours in calculations, like ranks and the total hours' +- key: notifications.discord_api_key + name: Discord API token + group: notifications + value: '' + options: '' + type: text + description: Discord API token for notifications +- key: 'notifications.discord_public_channel_id' + name: 'Discord Public Channel ID' + group: 'notifications' + value: '' + options: '' + type: 'text' + description: 'Discord public channel ID for broadcasat notifications' diff --git a/app/Events/BaseEvent.php b/app/Events/BaseEvent.php new file mode 100644 index 00000000..1a7b0b50 --- /dev/null +++ b/app/Events/BaseEvent.php @@ -0,0 +1,12 @@ +news = $news; + } +} diff --git a/app/Events/PirepAccepted.php b/app/Events/PirepAccepted.php index 988a377f..7619d721 100644 --- a/app/Events/PirepAccepted.php +++ b/app/Events/PirepAccepted.php @@ -3,24 +3,11 @@ namespace App\Events; use App\Models\Pirep; -use Illuminate\Broadcasting\InteractsWithSockets; -use Illuminate\Foundation\Events\Dispatchable; -use Illuminate\Queue\SerializesModels; -/** - * Class PirepAccepted - */ -class PirepAccepted +class PirepAccepted extends BaseEvent { - use Dispatchable, InteractsWithSockets, SerializesModels; - public $pirep; - /** - * PirepAccepted constructor. - * - * @param Pirep $pirep - */ public function __construct(Pirep $pirep) { $this->pirep = $pirep; diff --git a/app/Events/PirepFiled.php b/app/Events/PirepFiled.php index 560b0ca6..b9f6a3e6 100644 --- a/app/Events/PirepFiled.php +++ b/app/Events/PirepFiled.php @@ -3,13 +3,9 @@ namespace App\Events; use App\Models\Pirep; -use Illuminate\Broadcasting\InteractsWithSockets; -use Illuminate\Foundation\Events\Dispatchable; -use Illuminate\Queue\SerializesModels; -class PirepFiled +class PirepFiled extends BaseEvent { - use Dispatchable, InteractsWithSockets, SerializesModels; public $pirep; public function __construct(Pirep $pirep) diff --git a/app/Events/PirepRejected.php b/app/Events/PirepRejected.php index 66e421ce..1d78e1eb 100644 --- a/app/Events/PirepRejected.php +++ b/app/Events/PirepRejected.php @@ -3,24 +3,11 @@ namespace App\Events; use App\Models\Pirep; -use Illuminate\Broadcasting\InteractsWithSockets; -use Illuminate\Foundation\Events\Dispatchable; -use Illuminate\Queue\SerializesModels; -/** - * Class PirepRejected - */ -class PirepRejected +class PirepRejected extends BaseEvent { - use Dispatchable, InteractsWithSockets, SerializesModels; - public $pirep; - /** - * PirepRejected constructor. - * - * @param Pirep $pirep - */ public function __construct(Pirep $pirep) { $this->pirep = $pirep; diff --git a/app/Events/TestEvent.php b/app/Events/TestEvent.php index f5781047..27cb623e 100644 --- a/app/Events/TestEvent.php +++ b/app/Events/TestEvent.php @@ -3,24 +3,11 @@ namespace App\Events; use App\Models\User; -use Illuminate\Broadcasting\InteractsWithSockets; -use Illuminate\Foundation\Events\Dispatchable; -use Illuminate\Queue\SerializesModels; -/** - * Class TestEvent - */ -class TestEvent +class TestEvent extends BaseEvent { - use Dispatchable, InteractsWithSockets, SerializesModels; - public $user; - /** - * Create a new event instance. - * - * @param User $user - */ public function __construct(User $user) { $this->user = $user; diff --git a/app/Events/UserAccepted.php b/app/Events/UserAccepted.php index 21de3f70..738188d8 100644 --- a/app/Events/UserAccepted.php +++ b/app/Events/UserAccepted.php @@ -3,24 +3,11 @@ namespace App\Events; use App\Models\User; -use Illuminate\Broadcasting\InteractsWithSockets; -use Illuminate\Foundation\Events\Dispatchable; -use Illuminate\Queue\SerializesModels; -/** - * Class UserAccepted - */ -class UserAccepted +class UserAccepted extends BaseEvent { - use Dispatchable, InteractsWithSockets, SerializesModels; - public $user; - /** - * UserAccepted constructor. - * - * @param User $user - */ public function __construct(User $user) { $this->user = $user; diff --git a/app/Events/UserRegistered.php b/app/Events/UserRegistered.php index f2c501b2..7bf622f7 100644 --- a/app/Events/UserRegistered.php +++ b/app/Events/UserRegistered.php @@ -3,24 +3,11 @@ namespace App\Events; use App\Models\User; -use Illuminate\Broadcasting\InteractsWithSockets; -use Illuminate\Foundation\Events\Dispatchable; -use Illuminate\Queue\SerializesModels; -/** - * Class UserRegistered - */ -class UserRegistered +class UserRegistered extends BaseEvent { - use Dispatchable, InteractsWithSockets, SerializesModels; - public $user; - /** - * UserRegistered constructor. - * - * @param User $user - */ public function __construct(User $user) { $this->user = $user; diff --git a/app/Events/UserStateChanged.php b/app/Events/UserStateChanged.php index 4d686dc1..34291ae2 100644 --- a/app/Events/UserStateChanged.php +++ b/app/Events/UserStateChanged.php @@ -3,26 +3,15 @@ namespace App\Events; use App\Models\User; -use Illuminate\Broadcasting\InteractsWithSockets; -use Illuminate\Foundation\Events\Dispatchable; -use Illuminate\Queue\SerializesModels; /** * Event triggered when a user's state changes */ -class UserStateChanged +class UserStateChanged extends BaseEvent { - use Dispatchable, InteractsWithSockets, SerializesModels; - public $old_state; public $user; - /** - * UserStateChanged constructor. - * - * @param User $user - * @param $old_state - */ public function __construct(User $user, $old_state) { $this->old_state = $old_state; diff --git a/app/Events/UserStatsChanged.php b/app/Events/UserStatsChanged.php index 075a9156..211efcd5 100644 --- a/app/Events/UserStatsChanged.php +++ b/app/Events/UserStatsChanged.php @@ -3,26 +3,18 @@ namespace App\Events; use App\Models\User; -use Illuminate\Broadcasting\InteractsWithSockets; -use Illuminate\Foundation\Events\Dispatchable; -use Illuminate\Queue\SerializesModels; -/** - * Class UserStatsChanged - */ -class UserStatsChanged +class UserStatsChanged extends BaseEvent { - use Dispatchable, InteractsWithSockets, SerializesModels; - public $stat_name; public $old_value; public $user; /* * When a user's stats change. Stats changed match the field name: - * airport - * flights - * rank + * airport + * flights + * rank */ public function __construct(User $user, $stat_name, $old_value) { diff --git a/app/Http/Controllers/Admin/DashboardController.php b/app/Http/Controllers/Admin/DashboardController.php index 9d5a0fb7..81b007ce 100644 --- a/app/Http/Controllers/Admin/DashboardController.php +++ b/app/Http/Controllers/Admin/DashboardController.php @@ -4,9 +4,9 @@ namespace App\Http\Controllers\Admin; use App\Contracts\Controller; use App\Repositories\KvpRepository; -use App\Repositories\NewsRepository; use App\Repositories\PirepRepository; use App\Repositories\UserRepository; +use App\Services\NewsService; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Log; @@ -15,7 +15,7 @@ use Laracasts\Flash\Flash; class DashboardController extends Controller { private $kvpRepo; - private $newsRepo; + private $newsSvc; private $pirepRepo; private $userRepo; @@ -23,20 +23,20 @@ class DashboardController extends Controller * DashboardController constructor. * * @param KvpRepository $kvpRepo - * @param NewsRepository $newsRepo * @param PirepRepository $pirepRepo * @param UserRepository $userRepo + * @param $newsSvc */ public function __construct( KvpRepository $kvpRepo, - NewsRepository $newsRepo, + NewsService $newsSvc, PirepRepository $pirepRepo, UserRepository $userRepo ) { $this->kvpRepo = $kvpRepo; - $this->newsRepo = $newsRepo; $this->pirepRepo = $pirepRepo; $this->userRepo = $userRepo; + $this->newsSvc = $newsSvc; } /** @@ -93,10 +93,10 @@ class DashboardController extends Controller $attrs = $request->post(); $attrs['user_id'] = Auth::user()->id; - $this->newsRepo->create($attrs); + $this->newsSvc->addNews($attrs); } elseif ($request->isMethod('delete')) { - $news_id = $request->input('news_id'); - $this->newsRepo->delete($news_id); + $id = $request->input('news_id'); + $this->newsSvc->deleteNews($id); } return view('admin.dashboard.news', [ diff --git a/app/Listeners/BidEvents.php b/app/Listeners/BidEventHandler.php similarity index 57% rename from app/Listeners/BidEvents.php rename to app/Listeners/BidEventHandler.php index 2aed462d..fff8affa 100644 --- a/app/Listeners/BidEvents.php +++ b/app/Listeners/BidEventHandler.php @@ -4,14 +4,19 @@ namespace App\Listeners; use App\Contracts\Listener; use App\Events\PirepAccepted; +use App\Events\PirepRejected; use App\Services\BidService; -use Illuminate\Contracts\Events\Dispatcher; /** * Do stuff with bids - like if a PIREP is accepted, then remove the bid */ -class BidEvents extends Listener +class BidEventHandler extends Listener { + public static $callbacks = [ + PirepAccepted::class => 'onPirepAccept', + PirepRejected::class => 'onPirepReject', + ]; + private $bidSvc; public function __construct(BidService $bidSvc) @@ -19,17 +24,6 @@ class BidEvents extends Listener $this->bidSvc = $bidSvc; } - /** - * @param $events - */ - public function subscribe(Dispatcher $events): void - { - $events->listen( - PirepAccepted::class, - 'App\Listeners\BidEvents@onPirepAccept' - ); - } - /** * When a PIREP is accepted, remove any bids * @@ -43,4 +37,18 @@ class BidEvents extends Listener { $this->bidSvc->removeBidForPirep($event->pirep); } + + /** + * When a PIREP is accepted, remove any bids + * + * @param PirepRejected $event + * + * @throws \UnexpectedValueException + * @throws \InvalidArgumentException + * @throws \Exception + */ + public function onPirepReject(PirepRejected $event): void + { + $this->bidSvc->removeBidForPirep($event->pirep); + } } diff --git a/app/Listeners/ExpenseListener.php b/app/Listeners/ExpenseListener.php index 3329839a..3de6c596 100644 --- a/app/Listeners/ExpenseListener.php +++ b/app/Listeners/ExpenseListener.php @@ -5,9 +5,6 @@ namespace App\Listeners; use App\Contracts\Listener; use App\Events\Expenses; -/** - * Class ExpenseListener - */ class ExpenseListener extends Listener { /** diff --git a/app/Listeners/FinanceEvents.php b/app/Listeners/FinanceEventHandler.php similarity index 65% rename from app/Listeners/FinanceEvents.php rename to app/Listeners/FinanceEventHandler.php index 61548cd2..a3549bcb 100644 --- a/app/Listeners/FinanceEvents.php +++ b/app/Listeners/FinanceEventHandler.php @@ -6,41 +6,23 @@ use App\Contracts\Listener; use App\Events\PirepAccepted; use App\Events\PirepRejected; use App\Services\Finance\PirepFinanceService; -use Illuminate\Contracts\Events\Dispatcher; /** * Subscribe for events that we do some financial processing for * This includes when a PIREP is accepted, or rejected */ -class FinanceEvents extends Listener +class FinanceEventHandler extends Listener { private $financeSvc; - /** - * FinanceEvents constructor. - * - * @param PirepFinanceService $financeSvc - */ - public function __construct( - PirepFinanceService $financeSvc - ) { - $this->financeSvc = $financeSvc; - } + public static $callbacks = [ + PirepAccepted::class => 'onPirepAccept', + PirepRejected::class => 'onPirepReject', + ]; - /** - * @param $events - */ - public function subscribe(Dispatcher $events): void + public function __construct(PirepFinanceService $financeSvc) { - $events->listen( - PirepAccepted::class, - 'App\Listeners\FinanceEvents@onPirepAccept' - ); - - $events->listen( - PirepRejected::class, - 'App\Listeners\FinanceEvents@onPirepReject' - ); + $this->financeSvc = $financeSvc; } /** diff --git a/app/Listeners/SetUserActive.php b/app/Listeners/UserStateListener.php similarity index 93% rename from app/Listeners/SetUserActive.php rename to app/Listeners/UserStateListener.php index 2a484bf9..4937746f 100644 --- a/app/Listeners/SetUserActive.php +++ b/app/Listeners/UserStateListener.php @@ -7,7 +7,7 @@ use App\Events\PirepFiled; use App\Events\UserStateChanged; use App\Models\Enums\UserState; -class SetUserActive extends Listener +class UserStateListener extends Listener { public function handle(PirepFiled $event): void { diff --git a/app/Models/News.php b/app/Models/News.php index f34259d0..644b5a87 100644 --- a/app/Models/News.php +++ b/app/Models/News.php @@ -4,6 +4,10 @@ namespace App\Models; use App\Contracts\Model; +/** + * @property string subject + * @property string body + */ class News extends Model { public $table = 'news'; diff --git a/app/Notifications/Admin/UserRegistered.php b/app/Notifications/Admin/UserRegistered.php deleted file mode 100644 index 091db41c..00000000 --- a/app/Notifications/Admin/UserRegistered.php +++ /dev/null @@ -1,61 +0,0 @@ -user = $user; - } - - /** - * Get the notification's delivery channels. - * - * @param mixed $notifiable - * - * @return array - */ - public function via($notifiable) - { - return ['mail']; - } - - /** - * Get the mail representation of the notification. - * - * @param mixed $notifiable - * - * @return \Illuminate\Notifications\Messages\MailMessage - */ - public function toMail($notifiable) - { - return (new MailMessage()) - ->from(config('mail.from.address')) - ->markdown('mail.admin.user.registered') - ->subject('A new user registered') - ->with(['user' => $this->user]); - } - - public function toArray($notifiable) - { - return [ - 'user_id' => $this->user->id, - ]; - } -} diff --git a/app/Notifications/BaseNotification.php b/app/Notifications/BaseNotification.php new file mode 100644 index 00000000..3b68b31c --- /dev/null +++ b/app/Notifications/BaseNotification.php @@ -0,0 +1,41 @@ +channels = $notif_config[$klass]; + } + + /** + * Get the notification's delivery channels. + * + * @param mixed $notifiable + * + * @return array + */ + public function via($notifiable) + { + return $this->channels; + } +} diff --git a/app/Notifications/Channels/MailChannel.php b/app/Notifications/Channels/MailChannel.php new file mode 100644 index 00000000..3cb150b0 --- /dev/null +++ b/app/Notifications/Channels/MailChannel.php @@ -0,0 +1,41 @@ +mailSubject = $subject; + $this->mailTemplate = $template; + $this->mailTemplateArgs = $args; + } + + /** + * Get the mail representation of the notification. + * + * @param mixed $notifiable + * + * @return \Illuminate\Notifications\Messages\MailMessage + */ + public function toMail($notifiable) + { + return (new MailMessage()) + ->from(config('mail.from.address', 'no-reply@phpvms.net')) + ->subject($this->mailSubject) + ->markdown($this->mailTemplate, $this->mailTemplateArgs); + } +} diff --git a/app/Listeners/NotificationEvents.php b/app/Notifications/EventHandler.php similarity index 60% rename from app/Listeners/NotificationEvents.php rename to app/Notifications/EventHandler.php index 192d87de..f1fa94a0 100644 --- a/app/Listeners/NotificationEvents.php +++ b/app/Notifications/EventHandler.php @@ -1,8 +1,9 @@ 'onPirepAccepted', + PirepFiled::class => 'onPirepFile', + PirepRejected::class => 'onPirepRejected', + UserRegistered::class => 'onUserRegister', + UserStateChanged::class => 'onUserStateChange', + ]; + + public function __construct() { - $events->listen(UserRegistered::class, 'App\Listeners\NotificationEvents@onUserRegister'); - $events->listen(UserStateChanged::class, 'App\Listeners\NotificationEvents@onUserStateChange'); - $events->listen(PirepFiled::class, 'App\Listeners\NotificationEvents@onPirepFile'); - $events->listen(PirepAccepted::class, 'App\Listeners\NotificationEvents@onPirepAccepted'); - $events->listen(PirepRejected::class, 'App\Listeners\NotificationEvents@onPirepRejected'); + static::$broadcastNotifyable = app(Broadcast::class); } /** @@ -43,7 +50,7 @@ class NotificationEvents extends Listener try { Notification::send($admin_users, $notification); - } catch (\Exception $e) { + } catch (Exception $e) { Log::emergency('Error emailing admins, malformed email='.$e->getMessage()); } } @@ -56,7 +63,23 @@ class NotificationEvents extends Listener { try { $user->notify($notification); - } catch (\Exception $e) { + } catch (Exception $e) { + Log::emergency('Error emailing admins, malformed email='.$e->getMessage()); + } + } + + /** + * Send a notification to all users + * + * @param $notification + */ + protected function notifyAllUsers($notification) + { + $users = User::all()->get(); + + try { + Notification::send($users, $notification); + } catch (Exception $e) { Log::emergency('Error emailing admins, malformed email='.$e->getMessage()); } } @@ -70,21 +93,20 @@ class NotificationEvents extends Listener { Log::info('NotificationEvents::onUserRegister: ' .$event->user->ident.' is ' - .UserState::label($event->user->state) - .', sending active email'); + .UserState::label($event->user->state).', sending active email'); /* * Send all of the admins a notification that a new user registered */ - $this->notifyAdmins(new \App\Notifications\Admin\UserRegistered($event->user)); + $this->notifyAdmins(new Messages\AdminUserRegistered($event->user)); /* * Send the user a confirmation email */ if ($event->user->state === UserState::ACTIVE) { - $this->notifyUser($event->user, new \App\Notifications\UserRegistered($event->user)); + $this->notifyUser($event->user, new Messages\UserRegistered($event->user)); } elseif ($event->user->state === UserState::PENDING) { - $this->notifyUser($event->user, new \App\Notifications\UserPending($event->user)); + $this->notifyUser($event->user, new UserPending($event->user)); } } @@ -99,9 +121,9 @@ class NotificationEvents extends Listener if ($event->old_state === UserState::PENDING) { if ($event->user->state === UserState::ACTIVE) { - $this->notifyUser($event->user, new \App\Notifications\UserRegistered($event->user)); + $this->notifyUser($event->user, new Messages\UserRegistered($event->user)); } elseif ($event->user->state === UserState::REJECTED) { - $this->notifyUser($event->user, new \App\Notifications\UserRejected($event->user)); + $this->notifyUser($event->user, new UserRejected($event->user)); } } elseif ($event->old_state === UserState::ACTIVE) { Log::info('User state change from active to ??'); @@ -127,7 +149,7 @@ class NotificationEvents extends Listener public function onPirepAccepted(PirepAccepted $event): void { Log::info('NotificationEvents::onPirepAccepted: '.$event->pirep->id.' accepted'); - $this->notifyUser($event->pirep->user, new \App\Notifications\PirepAccepted($event->pirep)); + $this->notifyUser($event->pirep->user, new Messages\PirepAccepted($event->pirep)); } /** @@ -138,6 +160,17 @@ class NotificationEvents extends Listener public function onPirepRejected(PirepRejected $event): void { Log::info('NotificationEvents::onPirepRejected: '.$event->pirep->id.' rejected'); - $this->notifyUser($event->pirep->user, new \App\Notifications\PirepRejected($event->pirep)); + $this->notifyUser($event->pirep->user, new Messages\PirepRejected($event->pirep)); + } + + /** + * Notify all users of a news event + * + * @param \App\Events\NewsAdded $event + */ + public function onNewsAdded(NewsAdded $event): void + { + Log::info('NotificationEvents::onNewsAdded'); + $this->notifyAllUsers(new Messages\NewsAdded($event->news)); } } diff --git a/app/Notifications/Messages/AdminUserRegistered.php b/app/Notifications/Messages/AdminUserRegistered.php new file mode 100644 index 00000000..a007641b --- /dev/null +++ b/app/Notifications/Messages/AdminUserRegistered.php @@ -0,0 +1,38 @@ +user = $user; + $this->setMailable( + 'A new user registered', + 'notifications.mail.admin.user.registered', + ['user' => $user] + ); + } + + public function toArray($notifiable) + { + return [ + 'user_id' => $this->user->id, + ]; + } +} diff --git a/app/Notifications/Messages/NewsAdded.php b/app/Notifications/Messages/NewsAdded.php new file mode 100644 index 00000000..38ae343d --- /dev/null +++ b/app/Notifications/Messages/NewsAdded.php @@ -0,0 +1,40 @@ +news = $news; + $this->setMailable( + $news->subject, + 'notifications.mail.news', + ['news' => $news] + ); + } + + /** + * Get the array representation of the notification. + * + * @param mixed $notifiable + * + * @return array + */ + public function toArray($notifiable) + { + return [ + 'news_id' => $this->news->id, + ]; + } +} diff --git a/app/Notifications/Messages/PirepAccepted.php b/app/Notifications/Messages/PirepAccepted.php new file mode 100644 index 00000000..70979621 --- /dev/null +++ b/app/Notifications/Messages/PirepAccepted.php @@ -0,0 +1,50 @@ +pirep = $pirep; + + $this->setMailable( + 'PIREP Accepted!', + 'notifications.mail.pirep.accepted', + ['pirep' => $this->pirep] + ); + } + + /** + * Get the array representation of the notification. + * + * @param mixed $notifiable + * + * @return array + */ + public function toArray($notifiable) + { + return [ + 'pirep_id' => $this->pirep->id, + 'user_id' => $this->pirep->user_id, + ]; + } +} diff --git a/app/Notifications/Messages/PirepRejected.php b/app/Notifications/Messages/PirepRejected.php new file mode 100644 index 00000000..6c5ade9b --- /dev/null +++ b/app/Notifications/Messages/PirepRejected.php @@ -0,0 +1,47 @@ +pirep = $pirep; + + $this->setMailable( + 'PIREP Rejected!', + 'notifications.mail.pirep.rejected', + ['pirep' => $this->pirep] + ); + } + + /** + * Get the array representation of the notification. + * + * @param mixed $notifiable + * + * @return array + */ + public function toArray($notifiable) + { + return [ + 'pirep_id' => $this->pirep->id, + 'user_id' => $this->pirep->user_id, + ]; + } +} diff --git a/app/Notifications/Messages/PirepSubmitted.php b/app/Notifications/Messages/PirepSubmitted.php new file mode 100644 index 00000000..bcceedff --- /dev/null +++ b/app/Notifications/Messages/PirepSubmitted.php @@ -0,0 +1,47 @@ +pirep = $pirep; + + $this->setMailable( + 'New PIREP Submitted', + 'notifications.mail.admin.pirep.submitted', + ['pirep' => $this->pirep] + ); + } + + /** + * Get the array representation of the notification. + * + * @param mixed $notifiable + * + * @return array + */ + public function toArray($notifiable) + { + return [ + 'pirep_id' => $this->pirep->id, + 'user_id' => $this->pirep->user_id, + ]; + } +} diff --git a/app/Notifications/Messages/UserPending.php b/app/Notifications/Messages/UserPending.php new file mode 100644 index 00000000..000eb393 --- /dev/null +++ b/app/Notifications/Messages/UserPending.php @@ -0,0 +1,42 @@ +user = $user; + + $this->setMailable( + 'Your registration is pending', + 'notifications.mail.user.pending', + ['user' => $this->user] + ); + } + + /** + * Get the array representation of the notification. + * + * @param mixed $notifiable + * + * @return array + */ + public function toArray($notifiable) + { + return [ + 'user_id' => $this->user->id, + ]; + } +} diff --git a/app/Notifications/Messages/UserRegistered.php b/app/Notifications/Messages/UserRegistered.php new file mode 100644 index 00000000..0c766a44 --- /dev/null +++ b/app/Notifications/Messages/UserRegistered.php @@ -0,0 +1,39 @@ +user = $user; + + $this->setMailable( + 'Welcome to '.config('app.name').'!', + 'notifications.mail.user.registered', + ['user' => $this->user] + ); + } + + public function toArray($notifiable) + { + return [ + 'user_id' => $this->user->id, + ]; + } +} diff --git a/app/Notifications/Messages/UserRejected.php b/app/Notifications/Messages/UserRejected.php new file mode 100644 index 00000000..8c4b8079 --- /dev/null +++ b/app/Notifications/Messages/UserRejected.php @@ -0,0 +1,44 @@ +user = $user; + + $this->setMailable( + 'Your registration has been denied', + 'notifications.mail.user.rejected', + ['user' => $this->user] + ); + } + + /** + * Get the array representation of the notification. + * + * @param mixed $notifiable + * + * @return array + */ + public function toArray($notifiable) + { + return [ + 'user_id' => $this->user->id, + ]; + } +} diff --git a/app/Notifications/Backups.php b/app/Notifications/Notifiables/Backups.php similarity index 90% rename from app/Notifications/Backups.php rename to app/Notifications/Notifiables/Backups.php index f5f0668a..788ec97a 100644 --- a/app/Notifications/Backups.php +++ b/app/Notifications/Notifiables/Backups.php @@ -1,6 +1,6 @@ notify($eventclass); + */ +class Broadcast +{ + use Notifiable; + + /** + * Routing for Discord - the public channel ID that's used + */ + public function routeNotificationForDiscord() + { + return setting('notifications.discord_public_channel_id'); + } +} diff --git a/app/Notifications/PirepAccepted.php b/app/Notifications/PirepAccepted.php deleted file mode 100644 index 14479fb0..00000000 --- a/app/Notifications/PirepAccepted.php +++ /dev/null @@ -1,68 +0,0 @@ -pirep = $pirep; - } - - /** - * Get the notification's delivery channels. - * - * @param mixed $notifiable - * - * @return array - */ - public function via($notifiable) - { - return ['mail']; - } - - /** - * Get the mail representation of the notification. - * - * @param mixed $notifiable - * - * @return \Illuminate\Notifications\Messages\MailMessage - */ - public function toMail($notifiable) - { - return (new MailMessage()) - ->from(config('mail.from.address', 'no-reply@phpvms.net')) - ->subject('PIREP Accepted!') - ->markdown('mail.pirep.accepted', ['pirep' => $this->pirep]); - } - - /** - * Get the array representation of the notification. - * - * @param mixed $notifiable - * - * @return array - */ - public function toArray($notifiable) - { - return [ - 'pirep_id' => $this->pirep->id, - 'user_id' => $this->pirep->user_id, - ]; - } -} diff --git a/app/Notifications/PirepRejected.php b/app/Notifications/PirepRejected.php deleted file mode 100644 index 6242f867..00000000 --- a/app/Notifications/PirepRejected.php +++ /dev/null @@ -1,68 +0,0 @@ -pirep = $pirep; - } - - /** - * Get the notification's delivery channels. - * - * @param mixed $notifiable - * - * @return array - */ - public function via($notifiable) - { - return ['mail']; - } - - /** - * Get the mail representation of the notification. - * - * @param mixed $notifiable - * - * @return \Illuminate\Notifications\Messages\MailMessage - */ - public function toMail($notifiable) - { - return (new MailMessage()) - ->from(config('mail.from.address', 'no-reply@phpvms.net')) - ->subject('PIREP Rejected!') - ->markdown('mail.pirep.rejected', ['pirep' => $this->pirep]); - } - - /** - * Get the array representation of the notification. - * - * @param mixed $notifiable - * - * @return array - */ - public function toArray($notifiable) - { - return [ - 'pirep_id' => $this->pirep->id, - 'user_id' => $this->pirep->user_id, - ]; - } -} diff --git a/app/Notifications/PirepSubmitted.php b/app/Notifications/PirepSubmitted.php deleted file mode 100644 index 251000c8..00000000 --- a/app/Notifications/PirepSubmitted.php +++ /dev/null @@ -1,68 +0,0 @@ -pirep = $pirep; - } - - /** - * Get the notification's delivery channels. - * - * @param mixed $notifiable - * - * @return array - */ - public function via($notifiable) - { - return ['mail']; - } - - /** - * Get the mail representation of the notification. - * - * @param mixed $notifiable - * - * @return \Illuminate\Notifications\Messages\MailMessage - */ - public function toMail($notifiable) - { - return (new MailMessage()) - ->from(config('mail.from.address', 'no-reply@phpvms.net')) - ->subject('New PIREP Submitted') - ->markdown('mail.admin.pirep.submitted', ['pirep' => $this->pirep]); - } - - /** - * Get the array representation of the notification. - * - * @param mixed $notifiable - * - * @return array - */ - public function toArray($notifiable) - { - return [ - 'pirep_id' => $this->pirep->id, - 'user_id' => $this->pirep->user_id, - ]; - } -} diff --git a/app/Notifications/UserPending.php b/app/Notifications/UserPending.php deleted file mode 100644 index 0d9e762b..00000000 --- a/app/Notifications/UserPending.php +++ /dev/null @@ -1,65 +0,0 @@ -user = $user; - } - - /** - * Get the notification's delivery channels. - * - * @param mixed $notifiable - * - * @return array - */ - public function via($notifiable) - { - return ['mail']; - } - - /** - * Get the mail representation of the notification. - * - * @param mixed $notifiable - * - * @return \Illuminate\Notifications\Messages\MailMessage - */ - public function toMail($notifiable) - { - return (new MailMessage()) - ->from(config('mail.from.address', 'no-reply@phpvms.net')) - ->subject('Your registration is pending') - ->markdown('mail.user.pending', ['user' => $this->user]); - } - - /** - * Get the array representation of the notification. - * - * @param mixed $notifiable - * - * @return array - */ - public function toArray($notifiable) - { - return [ - 'user_id' => $this->user->id, - ]; - } -} diff --git a/app/Notifications/UserRegistered.php b/app/Notifications/UserRegistered.php deleted file mode 100644 index b32a9adf..00000000 --- a/app/Notifications/UserRegistered.php +++ /dev/null @@ -1,60 +0,0 @@ -user = $user; - } - - /** - * Get the notification's delivery channels. - * - * @param mixed $notifiable - * - * @return array - */ - public function via($notifiable) - { - return ['mail']; - } - - /** - * Get the mail representation of the notification. - * - * @param mixed $notifiable - * - * @return \Illuminate\Notifications\Messages\MailMessage - */ - public function toMail($notifiable) - { - return (new MailMessage()) - ->from(config('mail.from.address', 'no-reply@phpvms.net')) - ->subject('Welcome to '.config('app.name').'!') - ->markdown('mail.user.registered', ['user' => $this->user]); - } - - public function toArray($notifiable) - { - return [ - 'user_id' => $this->user->id, - ]; - } -} diff --git a/app/Notifications/UserRejected.php b/app/Notifications/UserRejected.php deleted file mode 100644 index 187144aa..00000000 --- a/app/Notifications/UserRejected.php +++ /dev/null @@ -1,65 +0,0 @@ -user = $user; - } - - /** - * Get the notification's delivery channels. - * - * @param mixed $notifiable - * - * @return array - */ - public function via($notifiable) - { - return ['mail']; - } - - /** - * Get the mail representation of the notification. - * - * @param mixed $notifiable - * - * @return \Illuminate\Notifications\Messages\MailMessage - */ - public function toMail($notifiable) - { - return (new MailMessage()) - ->from(config('mail.from.address', 'no-reply@phpvms.net')) - ->subject('Your registration has been denied') - ->markdown('mail.user.rejected', ['user' => $this->user]); - } - - /** - * Get the array representation of the notification. - * - * @param mixed $notifiable - * - * @return array - */ - public function toArray($notifiable) - { - return [ - 'user_id' => $this->user->id, - ]; - } -} diff --git a/app/Providers/EventServiceProvider.php b/app/Providers/EventServiceProvider.php index f2758991..6accec41 100755 --- a/app/Providers/EventServiceProvider.php +++ b/app/Providers/EventServiceProvider.php @@ -6,11 +6,11 @@ use App\Events\Expenses; use App\Events\PirepFiled; use App\Events\UserStatsChanged; use App\Listeners\AwardListener; -use App\Listeners\BidEvents; +use App\Listeners\BidEventHandler; use App\Listeners\ExpenseListener; -use App\Listeners\FinanceEvents; -use App\Listeners\NotificationEvents; -use App\Listeners\SetUserActive; +use App\Listeners\FinanceEventHandler; +use App\Listeners\UserStateListener; +use App\Notifications\EventHandler; use Illuminate\Auth\Events\Registered; use Illuminate\Auth\Listeners\SendEmailVerificationNotification; use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider; @@ -23,7 +23,7 @@ class EventServiceProvider extends ServiceProvider ], PirepFiled::class => [ - SetUserActive::class, + UserStateListener::class, ], Registered::class => [ @@ -36,8 +36,8 @@ class EventServiceProvider extends ServiceProvider ]; protected $subscribe = [ - BidEvents::class, - FinanceEvents::class, - NotificationEvents::class, + BidEventHandler::class, + FinanceEventHandler::class, + EventHandler::class, ]; } diff --git a/app/Services/AwardService.php b/app/Services/AwardService.php index 6fad9316..302fd9b4 100644 --- a/app/Services/AwardService.php +++ b/app/Services/AwardService.php @@ -4,6 +4,7 @@ namespace App\Services; use App\Contracts\Service; use App\Support\ClassLoader; +use function get_class; use Nwidart\Modules\Facades\Module; class AwardService extends Service @@ -18,9 +19,9 @@ class AwardService extends Service $awards = []; $formatted_awards = []; - // Find the awards in the app/Awards directory - $classes = ClassLoader::getClassesInPath(app_path('/Awards')); - $awards = array_merge($awards, $classes); + // Find the awards in the modules/Awards directory +// $classes = ClassLoader::getClassesInPath(module_path('Awards')); +// $awards = array_merge($awards, $classes); // Look throughout all the other modules, in the module/{MODULE}/Awards directory foreach (Module::all() as $module) { @@ -33,7 +34,7 @@ class AwardService extends Service } foreach ($awards as $award) { - $formatted_awards[\get_class($award)] = $award; + $formatted_awards[get_class($award)] = $award; } return $formatted_awards; diff --git a/app/Services/NewsService.php b/app/Services/NewsService.php new file mode 100644 index 00000000..17dd79e3 --- /dev/null +++ b/app/Services/NewsService.php @@ -0,0 +1,44 @@ +newsRepo = $newsRepo; + } + + /** + * Add a news item + * + * @param array $attrs + * + * @throws \Prettus\Validator\Exceptions\ValidatorException + * + * @return mixed + */ + public function addNews(array $attrs) + { + $news = $this->newsRepo->create($attrs); + event(new NewsAdded($news)); + + return $news; + } + + /** + * Delete something from the news items + * + * @param int $id ID of the news row to delete + */ + public function deleteNews($id) + { + $this->newsRepo->delete($id); + } +} diff --git a/config/backup.php b/config/backup.php index 4597f86d..78922107 100644 --- a/config/backup.php +++ b/config/backup.php @@ -1,6 +1,6 @@ [ + AdminUserRegistered::class => ['mail'], + NewsAdded::class => ['mail'], + PirepAccepted::class => ['mail'], + PirepRejected::class => ['mail'], + PirepSubmitted::class => ['mail'], + UserPending::class => ['mail'], + UserRegistered::class => ['mail'], + UserRejected::class => ['mail'], + ], +]; diff --git a/modules/.gitignore b/modules/.gitignore index ab3dacdd..4e7f20b3 100644 --- a/modules/.gitignore +++ b/modules/.gitignore @@ -3,6 +3,7 @@ /* /*/ !.gitignore +!/Awards !/Installer !/Sample !/Vacentral diff --git a/app/Awards/PilotFlightAwards.php b/modules/Awards/Awards/PilotFlightAwards.php similarity index 88% rename from app/Awards/PilotFlightAwards.php rename to modules/Awards/Awards/PilotFlightAwards.php index 2af6adbb..528b0e71 100644 --- a/app/Awards/PilotFlightAwards.php +++ b/modules/Awards/Awards/PilotFlightAwards.php @@ -1,12 +1,14 @@ subject }} + +$news->body + +@component('mail::button', ['url' => route('frontend.pireps.show', [$pirep->id])]) +View PIREP +@endcomponent + +Thanks,
+{{ config('app.name') }} +@endcomponent diff --git a/resources/views/mail/pirep/accepted.blade.php b/resources/views/notifications/mail/pirep/accepted.blade.php similarity index 100% rename from resources/views/mail/pirep/accepted.blade.php rename to resources/views/notifications/mail/pirep/accepted.blade.php diff --git a/resources/views/mail/pirep/rejected.blade.php b/resources/views/notifications/mail/pirep/rejected.blade.php similarity index 100% rename from resources/views/mail/pirep/rejected.blade.php rename to resources/views/notifications/mail/pirep/rejected.blade.php diff --git a/resources/views/mail/user/new_login_details.blade.php b/resources/views/notifications/mail/user/new_login_details.blade.php similarity index 100% rename from resources/views/mail/user/new_login_details.blade.php rename to resources/views/notifications/mail/user/new_login_details.blade.php diff --git a/resources/views/mail/user/pending.blade.php b/resources/views/notifications/mail/user/pending.blade.php similarity index 100% rename from resources/views/mail/user/pending.blade.php rename to resources/views/notifications/mail/user/pending.blade.php diff --git a/resources/views/mail/user/registered.blade.php b/resources/views/notifications/mail/user/registered.blade.php similarity index 100% rename from resources/views/mail/user/registered.blade.php rename to resources/views/notifications/mail/user/registered.blade.php diff --git a/resources/views/mail/user/rejected.blade.php b/resources/views/notifications/mail/user/rejected.blade.php similarity index 100% rename from resources/views/mail/user/rejected.blade.php rename to resources/views/notifications/mail/user/rejected.blade.php diff --git a/tests/AwardsTest.php b/tests/AwardsTest.php index 99a6dd40..8fba76ee 100644 --- a/tests/AwardsTest.php +++ b/tests/AwardsTest.php @@ -34,7 +34,7 @@ class AwardsTest extends TestCase { // Create one award that's given out with one flight $award = factory(App\Models\Award::class)->create([ - 'ref_model' => App\Awards\PilotFlightAwards::class, + 'ref_model' => Modules\Awards\Awards\PilotFlightAwards::class, 'ref_model_params' => 1, ]); diff --git a/tests/PIREPTest.php b/tests/PIREPTest.php index 622a64fa..48e6dc22 100644 --- a/tests/PIREPTest.php +++ b/tests/PIREPTest.php @@ -6,11 +6,13 @@ use App\Models\Enums\AcarsType; use App\Models\Enums\PirepState; use App\Models\Pirep; use App\Models\User; +use App\Notifications\Messages\PirepAccepted; use App\Repositories\SettingRepository; use App\Services\BidService; use App\Services\FlightService; use App\Services\PirepService; use Carbon\Carbon; +use Illuminate\Support\Facades\Notification; class PIREPTest extends TestCase { @@ -81,7 +83,6 @@ class PIREPTest extends TestCase * Now set the PIREP state to ACCEPTED */ $new_pirep_count = $pirep->pilot->flights + 1; - $original_flight_time = $pirep->pilot->flight_time; $new_flight_time = $pirep->pilot->flight_time + $pirep->flight_time; $this->pirepSvc->changeState($pirep, PirepState::ACCEPTED); @@ -96,6 +97,9 @@ class PIREPTest extends TestCase $this->get('/api/fleet/aircraft/'.$pirep->aircraft_id, [], $user) ->assertJson(['data' => ['airport_id' => $pirep->arr_airport_id]]); + // Make sure a notification was sent out to both the user and the admin(s) + Notification::assertSentTo([$user], PirepAccepted::class); + // Try cancelling it $uri = '/api/pireps/'.$pirep->id.'/cancel'; $response = $this->put($uri, [], [], $user); diff --git a/tests/TestCase.php b/tests/TestCase.php index 0a74418e..5fbaf526 100755 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -8,7 +8,7 @@ use GuzzleHttp\HandlerStack; use GuzzleHttp\Psr7\Response; use Illuminate\Routing\Middleware\ThrottleRequests; use Illuminate\Support\Facades\Artisan; -use Illuminate\Support\Facades\Mail; +use Illuminate\Support\Facades\Notification; use Tests\CreatesApplication; use Tests\TestData; @@ -46,7 +46,7 @@ class TestCase extends Illuminate\Foundation\Testing\TestCase ThrottleRequests::class ); - Mail::fake(); + Notification::fake(); Artisan::call('database:create', ['--reset' => true]); Artisan::call('migrate:refresh', ['--env' => 'testing']);