diff --git a/app/Bus/Handlers/Events/Component/SendComponentUpdateEmailNotificationHandler.php b/app/Bus/Handlers/Events/Component/SendComponentUpdateEmailNotificationHandler.php index 80f88e3b..695b351a 100644 --- a/app/Bus/Handlers/Events/Component/SendComponentUpdateEmailNotificationHandler.php +++ b/app/Bus/Handlers/Events/Component/SendComponentUpdateEmailNotificationHandler.php @@ -59,6 +59,7 @@ class SendComponentUpdateEmailNotificationHandler foreach (Subscription::isVerifiedForComponent($component->id)->with('subscriber')->get() as $subscription) { $subscriber = $subscription->subscriber; $mail['email'] = $subscriber->email; + $mail['manage_link'] = route('subscribe.manage', ['code' => $subscriber->verify_code]); $mail['unsubscribe_link'] = route('subscribe.unsubscribe', ['code' => $subscriber->verify_code, 'subscription' => $subscription->id]); $this->mailer->queue([ diff --git a/app/Bus/Handlers/Events/Incident/SendIncidentEmailNotificationHandler.php b/app/Bus/Handlers/Events/Incident/SendIncidentEmailNotificationHandler.php index cae51b33..177b910a 100644 --- a/app/Bus/Handlers/Events/Incident/SendIncidentEmailNotificationHandler.php +++ b/app/Bus/Handlers/Events/Incident/SendIncidentEmailNotificationHandler.php @@ -75,6 +75,7 @@ class SendIncidentEmailNotificationHandler 'html_content' => $incident->formattedMessage, 'text_content' => $incident->message, 'token' => $subscriber->token, + 'manage_link' => route('subscribe.manage', ['code' => $subscriber->verify_code]), 'unsubscribe_link' => route('subscribe.unsubscribe', ['code' => $subscriber->verify_code]), ]; diff --git a/app/Bus/Handlers/Events/Incident/SendMaintenanceEmailNotificationHandler.php b/app/Bus/Handlers/Events/Incident/SendMaintenanceEmailNotificationHandler.php index 54732bd2..f3e51c00 100644 --- a/app/Bus/Handlers/Events/Incident/SendMaintenanceEmailNotificationHandler.php +++ b/app/Bus/Handlers/Events/Incident/SendMaintenanceEmailNotificationHandler.php @@ -71,6 +71,7 @@ class SendMaintenanceEmailNotificationHandler 'text_content' => $data->message, 'scheduled_at' => $data->scheduled_at_formatted, 'token' => $subscriber->token, + 'manage_link' => route('subscribe.manage', ['code' => $subscriber->verify_code]), 'unsubscribe_link' => route('subscribe.unsubscribe', ['code' => $subscriber->verify_code]), ]; diff --git a/app/Composers/DashboardComposer.php b/app/Composers/DashboardComposer.php index 8f320fa6..89651d26 100644 --- a/app/Composers/DashboardComposer.php +++ b/app/Composers/DashboardComposer.php @@ -13,6 +13,7 @@ namespace CachetHQ\Cachet\Composers; use CachetHQ\Cachet\Models\Component; use CachetHQ\Cachet\Models\Incident; +use CachetHQ\Cachet\Models\Subscriber; use Illuminate\Contracts\View\View; class DashboardComposer @@ -28,5 +29,6 @@ class DashboardComposer { $view->withIncidentCount(Incident::notScheduled()->count()); $view->withComponentCount(Component::all()->count()); + $view->withSubscriberCount(Subscriber::isVerified()->count()); } } diff --git a/app/Foundation/Providers/ComposerServiceProvider.php b/app/Foundation/Providers/ComposerServiceProvider.php index d30e6d13..6d6fb313 100644 --- a/app/Foundation/Providers/ComposerServiceProvider.php +++ b/app/Foundation/Providers/ComposerServiceProvider.php @@ -34,7 +34,7 @@ class ComposerServiceProvider extends ServiceProvider $factory->composer('*', CurrentUserComposer::class); $factory->composer(['index'], MetricsComposer::class); $factory->composer(['index', 'incident', 'subscribe', 'signup'], StatusPageComposer::class); - $factory->composer(['index', 'incident', 'subscribe', 'signup', 'dashboard.settings.theme'], ThemeComposer::class); + $factory->composer(['index', 'incident', 'subscribe.*', 'signup', 'dashboard.settings.theme'], ThemeComposer::class); $factory->composer('dashboard.*', DashboardComposer::class); $factory->composer(['setup', 'dashboard.settings.localization'], TimezoneLocaleComposer::class); } diff --git a/app/Http/Controllers/SubscribeController.php b/app/Http/Controllers/SubscribeController.php index 3e417cf1..8ac61b19 100644 --- a/app/Http/Controllers/SubscribeController.php +++ b/app/Http/Controllers/SubscribeController.php @@ -42,7 +42,7 @@ class SubscribeController extends Controller */ public function showSubscribe() { - return View::make('subscribe') + return View::make('subscribe.subscribe') ->withAboutApp(Markdown::convertToHtml(Config::get('setting.app_about'))); } @@ -127,4 +127,26 @@ class SubscribeController extends Controller return Redirect::route('status-page') ->withSuccess(sprintf('%s %s', trans('dashboard.notifications.awesome'), trans('cachet.subscriber.email.unsubscribed'))); } + + /** + * Shows the subscription manager page. + * + * @param string|null $code + * + * @return \Illuminate\View\View + */ + public function showManage($code = null) + { + if ($code === null) { + throw new NotFoundHttpException(); + } + + $subscriber = Subscriber::where('verify_code', '=', $code)->first(); + + if (!$subscriber || !$subscriber->is_verified) { + throw new BadRequestHttpException(); + } + + return View::make('subscribe.manage')->withSubscriber($subscriber); + } } diff --git a/app/Http/Routes/SubscribeRoutes.php b/app/Http/Routes/SubscribeRoutes.php index 75384ebd..b4eb0b90 100644 --- a/app/Http/Routes/SubscribeRoutes.php +++ b/app/Http/Routes/SubscribeRoutes.php @@ -29,17 +29,20 @@ class SubscribeRoutes */ public function map(Registrar $router) { - $router->group(['middleware' => ['web', 'ready', 'localize'], 'as' => 'subscribe.'], function ($router) { - $router->group(['middleware' => ['subscribers']], function ($router) { - $router->get('subscribe', [ - 'as' => 'subscribe', - 'uses' => 'SubscribeController@showSubscribe', - ]); + $router->group(['middleware' => ['web', 'ready', 'localize', 'subscribers'], 'as' => 'subscribe.'], function ($router) { + $router->get('subscribe', [ + 'as' => 'subscribe', + 'uses' => 'SubscribeController@showSubscribe', + ]); - $router->post('subscribe', [ - 'uses' => 'SubscribeController@postSubscribe', - ]); - }); + $router->post('subscribe', [ + 'uses' => 'SubscribeController@postSubscribe', + ]); + + $router->get('subscribe/manage/{code}', [ + 'as' => 'manage', + 'uses' => 'SubscribeController@showManage', + ]); $router->get('subscribe/verify/{code}', [ 'as' => 'verify', diff --git a/app/Models/Subscriber.php b/app/Models/Subscriber.php index dba23d83..be456719 100644 --- a/app/Models/Subscriber.php +++ b/app/Models/Subscriber.php @@ -48,6 +48,13 @@ class Subscriber extends Model implements HasPresenter 'email' => 'required|email', ]; + /** + * The relations to eager load on every query. + * + * @var string[] + */ + protected $with = ['subscriptions']; + /** * Overrides the models boot method. */ diff --git a/app/Presenters/SubscriberPresenter.php b/app/Presenters/SubscriberPresenter.php index adf970b5..a1f59bbe 100644 --- a/app/Presenters/SubscriberPresenter.php +++ b/app/Presenters/SubscriberPresenter.php @@ -14,6 +14,7 @@ namespace CachetHQ\Cachet\Presenters; use CachetHQ\Cachet\Dates\DateFactory; use CachetHQ\Cachet\Presenters\Traits\TimestampsTrait; use Illuminate\Contracts\Support\Arrayable; +use Illuminate\Support\Facades\Config; use McCool\LaravelAutoPresenter\BasePresenter; class SubscriberPresenter extends BasePresenter implements Arrayable @@ -30,6 +31,16 @@ class SubscriberPresenter extends BasePresenter implements Arrayable return app(DateFactory::class)->make($this->wrappedObject->verified_at)->toDateTimeString(); } + /** + * Present formatted subscribed date. + * + * @return string + */ + public function subscribed_at() + { + return ucfirst(app(DateFactory::class)->make($this->wrappedObject->subscribed_at)->format(Config::get('setting.incident_date_format', 'l jS F Y H:i:s'))); + } + /** * Convert the presenter instance to an array. * diff --git a/resources/lang/en/cachet.php b/resources/lang/en/cachet.php index e5138db1..2f3a780b 100755 --- a/resources/lang/en/cachet.php +++ b/resources/lang/en/cachet.php @@ -63,10 +63,15 @@ return [ 'subscriber' => [ 'subscribe' => 'Subscribe to get the most recent updates', 'button' => 'Subscribe', + 'manage' => [ + 'no_subscriptions' => 'You\'re currently subscribed to all updates.', + 'my_subscriptions' => 'You\'re currently subscribed to the following updates.', + ], 'email' => [ 'subscribe' => 'Subscribe to email updates.', 'subscribed' => 'You\'ve been subscribed to email notifications, please check your email to confirm your subscription.', 'verified' => 'Your email subscription has been confirmed. Thank you!', + 'manage' => 'Manage your subscription.', 'unsubscribe' => 'Unsubscribe from email updates.', 'unsubscribed' => 'Your email subscription has been cancelled.', 'failure' => 'Something went wrong with the subscription.', diff --git a/resources/lang/en/dashboard.php b/resources/lang/en/dashboard.php index f43a3493..b20ed8ab 100755 --- a/resources/lang/en/dashboard.php +++ b/resources/lang/en/dashboard.php @@ -140,11 +140,13 @@ return [ ], // Subscribers 'subscribers' => [ - 'subscribers' => 'Subscribers', - 'description' => 'Subscribers will receive email updates when incidents are created.', - 'verified' => 'Verified', - 'not_verified' => 'Not verified', - 'add' => [ + 'subscribers' => 'Subscribers', + 'description' => 'Subscribers will receive email updates when incidents are created or components are updated.', + 'verified' => 'Verified', + 'not_verified' => 'Not verified', + 'subscriber' => ':email, subscribed :date', + 'no_subscriptions' => 'Subscribed to all updates', + 'add' => [ 'title' => 'Add a new subscriber', 'success' => 'Subscriber has been added!', 'failure' => 'Something went wrong with the component.', diff --git a/resources/views/dashboard/partials/sidebar.blade.php b/resources/views/dashboard/partials/sidebar.blade.php index a3321016..c8da3316 100644 --- a/resources/views/dashboard/partials/sidebar.blade.php +++ b/resources/views/dashboard/partials/sidebar.blade.php @@ -60,6 +60,7 @@ {{ trans('dashboard.subscribers.subscribers') }} + {{ $subscriber_count }}
{{ trans('dashboard.subscribers.description') }}
+{{ trans('dashboard.subscribers.description') }}
-{{ $subscriber->email }}
+{{ trans('dashboard.subscribers.subscriber', ['email' => $subscriber->email, 'date' => $subscriber->subscribed_at]) }}
+{{ trans('dashboard.subscribers.no_subscriptions') }}
+ @endif +{{ $subscriber->created_at }}
-{!! trans('cachet.powered_by', ['app' => $app_name]) !!}
@endif ++ {!! trans('cachet.subscriber.email.manage') !!} +
{!! trans('cachet.subscriber.email.unsubscribe') !!}
diff --git a/resources/views/emails/components/update-text.blade.php b/resources/views/emails/components/update-text.blade.php index 297287e4..10b880fb 100644 --- a/resources/views/emails/components/update-text.blade.php +++ b/resources/views/emails/components/update-text.blade.php @@ -4,4 +4,6 @@ {!! trans('cachet.powered_by', ['app' => $app_name]) !!} @endif +{!! trans('cachet.subscriber.email.manage') !!} {{ $manage_link }} + {!! trans('cachet.subscriber.email.unsubscribe') !!} {{ $unsubscribe_link }} diff --git a/resources/views/emails/incidents/maintenance-html.blade.php b/resources/views/emails/incidents/maintenance-html.blade.php index b734a634..3a200212 100644 --- a/resources/views/emails/incidents/maintenance-html.blade.php +++ b/resources/views/emails/incidents/maintenance-html.blade.php @@ -5,22 +5,25 @@ @stop @section('content') - {!! trans('cachet.subscriber.email.maintenance.html', ['app_name' => $app_name]) !!} +{!! trans('cachet.subscriber.email.maintenance.html', ['app_name' => $app_name]) !!} -{{ $scheduled_at }}
+{{ $scheduled_at }}
-- {!! $status !!} -
++ {!! $status !!} +
-- {!! $html_content !!} -
++ {!! $html_content !!} +
- @if($show_support) -{!! trans('cachet.powered_by', ['app' => $app_name]) !!}
- @endif -- {!! trans('cachet.subscriber.email.unsubscribe') !!} -
+@if($show_support) +{!! trans('cachet.powered_by', ['app' => $app_name]) !!}
+@endif ++ {!! trans('cachet.subscriber.email.manage') !!} +
++ {!! trans('cachet.subscriber.email.unsubscribe') !!} +
@stop diff --git a/resources/views/emails/incidents/maintenance-text.blade.php b/resources/views/emails/incidents/maintenance-text.blade.php index ea0346a3..81c33dfe 100644 --- a/resources/views/emails/incidents/maintenance-text.blade.php +++ b/resources/views/emails/incidents/maintenance-text.blade.php @@ -10,4 +10,6 @@ {!! trans('cachet.powered_by', ['app' => $app_name]) !!} @endif +{!! trans('cachet.subscriber.email.manage') !!} {{ $manage_link }} + {!! trans('cachet.subscriber.email.unsubscribe') !!} {{ $unsubscribe_link }} diff --git a/resources/views/emails/incidents/new-html.blade.php b/resources/views/emails/incidents/new-html.blade.php index 60d8583c..ec35fefb 100644 --- a/resources/views/emails/incidents/new-html.blade.php +++ b/resources/views/emails/incidents/new-html.blade.php @@ -5,23 +5,26 @@ @stop @section('content') - {!! trans('cachet.subscriber.email.incident.html-preheader', ['app_name' => $app_name]) !!} +{!! trans('cachet.subscriber.email.incident.html-preheader', ['app_name' => $app_name]) !!} -- {!! $status !!} - @if($has_component) - ({{ $component_name }}) - @endif -
- -- {!! $html_content !!} -
- - @if($show_support) -{!! trans('cachet.powered_by', ['app' => $app_name]) !!}
++ {!! $status !!} + @if($has_component) + ({{ $component_name }}) @endif -
- {!! trans('cachet.subscriber.email.unsubscribe') !!} -
+ + ++ {!! $html_content !!} +
+ +@if($show_support) +{!! trans('cachet.powered_by', ['app' => $app_name]) !!}
+@endif ++ {!! trans('cachet.subscriber.email.manage') !!} +
++ {!! trans('cachet.subscriber.email.unsubscribe') !!} +
@stop diff --git a/resources/views/emails/incidents/new-text.blade.php b/resources/views/emails/incidents/new-text.blade.php index 3386519d..e5d32c84 100644 --- a/resources/views/emails/incidents/new-text.blade.php +++ b/resources/views/emails/incidents/new-text.blade.php @@ -11,4 +11,6 @@ {!! trans('cachet.powered_by', ['app' => $app_name]) !!} @endif +{!! trans('cachet.subscriber.email.manage') !!} {{ $manage_link }} + {!! trans('cachet.subscriber.email.unsuscribe') !!} {{ $unsubscribe_link }} diff --git a/resources/views/signup.blade.php b/resources/views/signup.blade.php deleted file mode 100644 index cd9c3a92..00000000 --- a/resources/views/signup.blade.php +++ /dev/null @@ -1,47 +0,0 @@ -@extends('layout.master') - -@section('content') - - - - - @if($app_banner) - - @endif - - @include('dashboard.partials.errors') - -{{ trans('cachet.subscriber.manage.my_subscriptions') }}
+{{ trans('cachet.subscriber.manage.no_subscriptions') }}
+