From: Louis Jeckel Date: Wed, 9 Sep 2020 10:32:25 +0000 (+0200) Subject: add discover user support X-Git-Url: http://git.cubedesigners.com/?a=commitdiff_plain;h=0a6c21e6c92e4544e38cef257a37d5669b507a9b;p=psq.git add discover user support --- diff --git a/app/Http/Controllers/Admin/PublishController.php b/app/Http/Controllers/Admin/PublishController.php index 2566814..a83252d 100644 --- a/app/Http/Controllers/Admin/PublishController.php +++ b/app/Http/Controllers/Admin/PublishController.php @@ -69,7 +69,7 @@ class PublishController extends Controller public function recipientsCount() { - return ['data' => \App\User::recievesEmails()->count()]; + return ['data' => \App\User::receivesEmails()->count()]; } /** diff --git a/app/Http/Controllers/FlowpaperController.php b/app/Http/Controllers/FlowpaperController.php index 5887ab0..da401c0 100644 --- a/app/Http/Controllers/FlowpaperController.php +++ b/app/Http/Controllers/FlowpaperController.php @@ -38,6 +38,17 @@ class FlowpaperController extends Controller } + public function discover(PdfFile $file, Request $request) + { + if (! $request->hasValidSignature()) { + abort(401); + } + AccessLog::log($request, $file); + return $file->view(); + + } + + /** * @param PdfFile $file * @param Request $request diff --git a/app/Http/Middleware/LoginWithToken.php b/app/Http/Middleware/LoginWithToken.php index 9ca5f28..d0b753e 100644 --- a/app/Http/Middleware/LoginWithToken.php +++ b/app/Http/Middleware/LoginWithToken.php @@ -3,6 +3,7 @@ namespace App\Http\Middleware; use App\LoginToken; +use App\User; use Closure; class LoginWithToken @@ -18,6 +19,11 @@ class LoginWithToken public function handle($request, Closure $next, $delete = true) { LoginToken::checkAndLogin($request, filter_var($delete, FILTER_VALIDATE_BOOLEAN)); + if(\Auth::check()) { + /** @var User $user */ + $user = \Auth::user(); + $user->markEmailAsVerified(); + } return $next($request); } diff --git a/app/Imports/UsersImport.php b/app/Imports/UsersImport.php index d4fdad7..ced033c 100644 --- a/app/Imports/UsersImport.php +++ b/app/Imports/UsersImport.php @@ -58,6 +58,7 @@ class UsersImport implements ToModel, WithValidation, WithHeadingRow 'city' => $row['city'], 'phone' => $phone, 'password' => \Hash::make(Str::random()), + 'type' => $row['user_type'] ?? User::TYPE_SUBSCRIBER ]); } diff --git a/app/Jobs/ProcessEmailBatch.php b/app/Jobs/ProcessEmailBatch.php index 015b338..00fca96 100644 --- a/app/Jobs/ProcessEmailBatch.php +++ b/app/Jobs/ProcessEmailBatch.php @@ -43,7 +43,7 @@ class ProcessEmailBatch implements ShouldQueue $this->batch = $batch; $this->type = $type; $this->users = $recipientGroup === null ? - User::recievesEmails()->get() : + User::receivesEmails()->get() : PublishController::sendGroups()[$recipientGroup['slug']]['builder']->get(); } @@ -87,7 +87,7 @@ class ProcessEmailBatch implements ShouldQueue $fileVar = $this->batch->file === null ? [] : - ['file_url' => $this->batch->file->getUrlWithToken($user)]; + ['file_url' => $this->batch->file->getMailableUrl($user)]; return [ diff --git a/app/Notifications/EmailValidated.php b/app/Notifications/EmailValidated.php index d6038dd..c7a6a9e 100644 --- a/app/Notifications/EmailValidated.php +++ b/app/Notifications/EmailValidated.php @@ -42,9 +42,8 @@ class EmailValidated extends Notification public function toMail($notifiable) { return (new MailMessage) - ->subject('Inscription réussie !') - ->line("Bienvenue ! Vous bénéficiez dès aujourd'hui d'une période d'essai de ".User::trialDurationDays." jours.") - ->line('Merci [....]'); + ->subject('Email validé !') + ->line("Votre adresse email à bien été validée."); } /** diff --git a/app/Nova/Actions/StartTrial.php b/app/Nova/Actions/StartTrial.php index 97f5c62..3c9fad6 100644 --- a/app/Nova/Actions/StartTrial.php +++ b/app/Nova/Actions/StartTrial.php @@ -16,12 +16,11 @@ class StartTrial extends Action public $showOnTableRow = true; public $confirmButtonText = "Appliquer"; - public $name = "Démarrer période d'essai"; + public $name = "Démarrer période de découverte"; public function __construct() { - $this->confirmText = sprintf("Etes vous sûr de vouloir activer une période d'essai de %d jours ?", User::trialDurationDays); - + $this->confirmText = sprintf("Etes vous sûr de vouloir activer une période de découverte de %d jours ?", User::TRIAL_DURATION_DAYS); } @@ -36,9 +35,9 @@ class StartTrial extends Action */ public function handle(ActionFields $fields, Collection $models) { - $models->map->startTrial(); + $models->map->startDiscover(); - return Action::message(sprintf("La période d'essai à bien été activée pour %d utilisteur(s)", $models->count())); + return Action::message(sprintf("La période de découverte à bien été activée pour %d utilisteur(s)", $models->count())); } /** diff --git a/app/Nova/DiscoverUsers.php b/app/Nova/DiscoverUsers.php new file mode 100644 index 0000000..f5350a1 --- /dev/null +++ b/app/Nova/DiscoverUsers.php @@ -0,0 +1,28 @@ +where('type', 1); - } - } diff --git a/app/Nova/SpecialUsers.php b/app/Nova/SpecialUsers.php index b0fa75f..d35cfa4 100644 --- a/app/Nova/SpecialUsers.php +++ b/app/Nova/SpecialUsers.php @@ -9,6 +9,7 @@ use Laravel\Nova\Http\Requests\NovaRequest; class SpecialUsers extends User { public static $group = "Annuaire"; + public static $type = \App\User::TYPE_SPECIAL; public static function label() @@ -21,9 +22,6 @@ class SpecialUsers extends User return "Utilisateur (autre)"; } - public static function indexQuery(NovaRequest $request, $query) - { - return $query->where('type', 2); - } + } diff --git a/app/Nova/Subscriber.php b/app/Nova/Subscriber.php index 3901448..d30ef1b 100644 --- a/app/Nova/Subscriber.php +++ b/app/Nova/Subscriber.php @@ -24,10 +24,6 @@ class Subscriber extends User } - public static function indexQuery(NovaRequest $request, $query) - { - return $query->where('type', 0); - } public function filters(Request $request) { diff --git a/app/Nova/User.php b/app/Nova/User.php index 03cad55..9c4a0be 100644 --- a/app/Nova/User.php +++ b/app/Nova/User.php @@ -34,6 +34,7 @@ class User extends Resource */ public static $model = AppUser::class; + public static $type; /** @@ -74,8 +75,9 @@ class User extends Resource Select::make('Type')->options([ AppUser::TYPE_SUBSCRIBER => 'Abonné', AppUser::TYPE_PROSPECT => 'Prospect', - AppUser::TYPE_SPECIAL => 'Autre' - ])->hideFromIndex()->required(), + AppUser::TYPE_SPECIAL => 'Autre', + AppUser::TYPE_DISCOVER => 'Découverte', + ])->hideFromIndex()->required()->withMeta(['value' => $this->type ?? static::$type ?? AppUser::TYPE_SUBSCRIBER]), Badge::make('Etat', fn() => AppUser::STATUSES[$this->status]['label']) ->map(Arr::pluck(AppUser::STATUSES, 'badge', 'label')), ]; @@ -98,6 +100,14 @@ class User extends Resource } + public static function indexQuery(NovaRequest $request, $query) + { + return static::$type === null ? + $query : + $query->where('type', static::$type); + } + + /** * Get the cards available for the request. * diff --git a/app/PdfFile.php b/app/PdfFile.php index 69fb18e..cb61ccc 100644 --- a/app/PdfFile.php +++ b/app/PdfFile.php @@ -353,7 +353,26 @@ class PdfFile extends TwillModel implements Sortable return $user->routeWithToken('flowpaper.view', ['file' => $this->slug]); } + /** + * @return string + * Returns a signed url for trial users + */ + public function getSignedUrl(): string + { + return \URL::signedRoute('flowpaper.discover', ['file' => $this->slug]); + } + + /** + * @param User $user + * @return string + */ + public function getMailableUrl(User $user): string + { + return ($user->type === User::TYPE_DISCOVER) ? + $this->getSignedUrl() : + $this->getUrlWithToken($user); + } diff --git a/app/Providers/NovaServiceProvider.php b/app/Providers/NovaServiceProvider.php index d2697a9..9df3459 100644 --- a/app/Providers/NovaServiceProvider.php +++ b/app/Providers/NovaServiceProvider.php @@ -7,6 +7,7 @@ use Anaseqal\NovaImport\NovaImport; use App\Nova\Metrics\FileAccess; use App\Nova\Metrics\MailEvents; use App\Nova\Metrics\MailEventsPartition; +use App\Nova\Metrics\RegistrationCompletePartition; use App\Nova\Metrics\TotalUsers; use App\Nova\Metrics\UsersPartition; use Illuminate\Support\Facades\Gate; @@ -65,8 +66,10 @@ class NovaServiceProvider extends NovaApplicationServiceProvider new TotalUsers, new UsersPartition, new FileAccess, - new MailEvents('opened', 'Mails ouverts'), + new MailEvents('clicked', 'Mails cliqués'), new MailEventsPartition, + new RegistrationCompletePartition + ]; } diff --git a/app/User.php b/app/User.php index 6a5bbb9..93cdeae 100644 --- a/app/User.php +++ b/app/User.php @@ -29,10 +29,13 @@ use Laravel\Scout\Searchable; * @property string $position * @property bool $orgIsSubscribed (is user has org subscribed) * @property Carbon $trial_ends_at (is user is on trial) + * @property Carbon $discover_ends_at * @property bool self_registered (if user used /register) * @property string $employer (used if self registered) * @property int $type + * @property bool $unsubscribed * @property bool $reg_complete + * * @property string $status */ class User extends Authenticatable implements MustVerifyEmail @@ -80,6 +83,7 @@ class User extends Authenticatable implements MustVerifyEmail 'reg_complete' => 'bool', 'trial_ends_at' => 'datetime', 'active_until' => 'datetime', + 'discover_ends_at' => 'datetime', 'self_registered' => 'bool', 'early_access' => 'bool', ]; @@ -88,7 +92,11 @@ class User extends Authenticatable implements MustVerifyEmail /** * Trial duration in days */ - public const trialDurationDays = 14; + public const TRIAL_DURATION_DAYS = 14; + /** + * Discover duration in days + */ + public const DISCOVER_DURATION_DAYS = 14; /** * Possible Statuses @@ -117,6 +125,18 @@ class User extends Authenticatable implements MustVerifyEmail 'special' => [ 'badge' => 'warning', 'label' => 'Trimestriel', + ], + 'discover' => [ + 'badge' => 'info', + 'label' => 'Découverte', + ], + 'discover_expired' => [ + 'badge' => 'warning', + 'label' => 'Découverte expiré', + ], + 'unsubscribed' => [ + 'badge' => 'danger', + 'label' => 'Désabonné', ] ]; @@ -124,7 +144,7 @@ class User extends Authenticatable implements MustVerifyEmail public const TYPE_SUBSCRIBER = 0; public const TYPE_PROSPECT = 1; public const TYPE_SPECIAL = 2; - + public const TYPE_DISCOVER = 3; /** * @return array @@ -192,7 +212,17 @@ class User extends Authenticatable implements MustVerifyEmail */ public function startTrial(): void { - $this->trial_ends_at = now()->addDays(self::trialDurationDays); + $this->trial_ends_at = now()->addDays(self::TRIAL_DURATION_DAYS); + $this->save(); + } + + /** + * Starts discover period + */ + public function startDiscover(): void + { + $this->discover_ends_at = now()->addDays(self::DISCOVER_DURATION_DAYS); + $this->type = self::TYPE_DISCOVER; $this->save(); } @@ -226,19 +256,32 @@ class User extends Authenticatable implements MustVerifyEmail $o->isSubscribed(); } + /** + * @return bool + */ + public function isOnDiscovery(): bool + { + return $this->discover_ends_at !== null && + $this->discover_ends_at->isFuture(); + } + + + /** * SCOPES */ + + /** * @param Builder $builder */ - public function scopeRecievesEmails(Builder $builder): void + public function scopeReceivesEmails(Builder $builder): void { -// $builder->where('id', 1); - $builder->hasActiveSubscription()->orWhere->isOnTrial(); + $builder->where('unsubscribed', '0'); + $builder->hasActiveSubscription()->orWhere->isOnTrial()->orWhere->isOnDiscovery(); } /** @@ -249,6 +292,25 @@ class User extends Authenticatable implements MustVerifyEmail $builder->whereDate('trial_ends_at', '>', now()); } + + /** + * @param Builder $builder + */ + public function scopeIsOnDiscovery(Builder $builder): void + { + $builder->whereDate('discover_ends_at', '>', now()); + } + + + + /** + * @param Builder $builder + */ + public function scopeHasActiveSubscription(Builder $builder): void + { + $builder->hasOrgSubscription()->orWhere->hasIndSubscription(); + } + /** * @param Builder $builder */ @@ -277,25 +339,24 @@ class User extends Authenticatable implements MustVerifyEmail /** * @param Builder $builder */ - public function scopeHasActiveSubscription(Builder $builder): void + public function scopeProspect(Builder $builder): void { - $builder->hasOrgSubscription()->orWhere->hasIndSubscription(); + $builder->where('type', self::TYPE_PROSPECT); } /** * @param Builder $builder */ - public function scopeProspect(Builder $builder): void + public function scopeRegisteredUser(Builder $builder): void { - $builder->where('type', self::TYPE_PROSPECT); + $builder->where('type', self::TYPE_SUBSCRIBER); } - /** * @param Builder $builder */ - public function scopeRegisteredUser(Builder $builder): void + public function scopeDiscoverUser(Builder $builder): void { - $builder->where('type', self::TYPE_SUBSCRIBER); + $builder->where('type', self::TYPE_DISCOVER); } /** @@ -349,6 +410,10 @@ class User extends Authenticatable implements MustVerifyEmail { $id = 'inactive'; + if($this->unsubscribed) { + return 'unsubscribed'; + } + switch($this->type) { case self::TYPE_SUBSCRIBER: if($this->orgIsSubscribed) { @@ -369,6 +434,17 @@ class User extends Authenticatable implements MustVerifyEmail case self::TYPE_SPECIAL: $id = 'special'; break; + + case self::TYPE_DISCOVER: + if($this->isOnDiscovery()) { + $id = 'discover'; + } else if ($this->discover_ends_at === null){ + $id = 'inactive'; + } else { + $id = 'discover_expired'; + } + + break; } diff --git a/database/migrations/2020_09_09_093140_add_discover_until_column_to_users_table.php b/database/migrations/2020_09_09_093140_add_discover_until_column_to_users_table.php new file mode 100644 index 0000000..fda9c93 --- /dev/null +++ b/database/migrations/2020_09_09_093140_add_discover_until_column_to_users_table.php @@ -0,0 +1,32 @@ +dateTime('discover_ends_at')->nullable(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('users', function (Blueprint $table) { + $table->dropColumn('discover_ends_at'); + }); + } +} diff --git a/database/migrations/2020_09_09_093901_add_unsubscribe_column_to_users_table.php b/database/migrations/2020_09_09_093901_add_unsubscribe_column_to_users_table.php new file mode 100644 index 0000000..e98130f --- /dev/null +++ b/database/migrations/2020_09_09_093901_add_unsubscribe_column_to_users_table.php @@ -0,0 +1,32 @@ +boolean('unsubscribed')->default(0); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('users', function (Blueprint $table) { + $table->dropColumn('unsubscribed'); + }); + } +} diff --git a/resources/views/social-articles/show.blade.php b/resources/views/social-articles/show.blade.php index a9399a5..cce5113 100644 --- a/resources/views/social-articles/show.blade.php +++ b/resources/views/social-articles/show.blade.php @@ -19,7 +19,7 @@
{!! $article->getTruncatedContent() !!}
-
+
Cet article est réservé aux abonnés ! Pour y accéder merci de vous connecter, ou cliquez ici pour découvrir nos formules d'abonnement.
diff --git a/routes/web.php b/routes/web.php index 00cd5cd..ca64a42 100644 --- a/routes/web.php +++ b/routes/web.php @@ -47,6 +47,8 @@ Route::domain(env('CLIENT_DOMAIN_NAME'))->group(function() { ->get('/view/{file:slug}', 'FlowpaperController@view') ->name('flowpaper.view'); + Route::get('/discover/{file:slug}', 'FlowpaperController@discover')->name('flowpaper.discover'); + Route::get('edition/{file:slug}', 'FileController@show');