]> _ Git - psq.git/commitdiff
add discover user support
authorLouis Jeckel <louis.jeckel@outlook.cm>
Wed, 9 Sep 2020 10:32:25 +0000 (12:32 +0200)
committerLouis Jeckel <louis.jeckel@outlook.cm>
Wed, 9 Sep 2020 10:32:25 +0000 (12:32 +0200)
19 files changed:
app/Http/Controllers/Admin/PublishController.php
app/Http/Controllers/FlowpaperController.php
app/Http/Middleware/LoginWithToken.php
app/Imports/UsersImport.php
app/Jobs/ProcessEmailBatch.php
app/Notifications/EmailValidated.php
app/Nova/Actions/StartTrial.php
app/Nova/DiscoverUsers.php [new file with mode: 0644]
app/Nova/Prospect.php
app/Nova/SpecialUsers.php
app/Nova/Subscriber.php
app/Nova/User.php
app/PdfFile.php
app/Providers/NovaServiceProvider.php
app/User.php
database/migrations/2020_09_09_093140_add_discover_until_column_to_users_table.php [new file with mode: 0644]
database/migrations/2020_09_09_093901_add_unsubscribe_column_to_users_table.php [new file with mode: 0644]
resources/views/social-articles/show.blade.php
routes/web.php

index 25668141970e35eaa5f81c6368c5856ddc4e15bd..a83252d55757cd7ad5d0f67dcd3a0cf0940130b9 100644 (file)
@@ -69,7 +69,7 @@ class PublishController extends Controller
 
     public function recipientsCount()
     {
-        return ['data' => \App\User::recievesEmails()->count()];
+        return ['data' => \App\User::receivesEmails()->count()];
     }
 
     /**
index 5887ab067e9887e47ca2c9387e428aa7042dac62..da401c0bdc4ec0cfae62e7fea470d2e1e2f5c79f 100644 (file)
@@ -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
index 9ca5f289abd5cfb61dd560d79efda19728cd263e..d0b753eb4c921b1d644360257f2bb1e577a85f7a 100644 (file)
@@ -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);
     }
index d4fdad784be18af10fc265bfcd95185a0a4284d3..ced033c1f08ac46e1fdd81e11aaa91904d53f9a3 100644 (file)
@@ -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
         ]);
     }
 
index 015b33894993ff6fe947c2bbee5c2e5a1c0e8687..00fca96d6fa6ff7170ae2c5c640c54b8981e77d2 100644 (file)
@@ -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 [
index d6038dd3a54d8e9b3df61810acc85622a3bc05a9..c7a6a9e40c178009999517efc64848a03c844bd9 100644 (file)
@@ -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.");
     }
 
     /**
index 97f5c621a64cb00b67547492a1bb9ca313f27412..3c9fad6727199871aaa32766bb0079b4cdbe6b6f 100644 (file)
@@ -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 (file)
index 0000000..f5350a1
--- /dev/null
@@ -0,0 +1,28 @@
+<?php
+
+
+namespace App\Nova;
+
+
+use Laravel\Nova\Http\Requests\NovaRequest;
+
+class DiscoverUsers extends User
+{
+    public static $group = "Annuaire";
+
+    public static $type = \App\User::TYPE_DISCOVER;
+
+
+    public static function label()
+    {
+        return "Utilisateurs découverte";
+    }
+
+    public static function singularLabel()
+    {
+        return "Utilisateur (découverte)";
+    }
+
+
+
+}
index 8f782cc2bdff0e53b75c6275889f563de6d47be2..3a3a655530299ea3c50d55fc69cfbd7042fdecd3 100644 (file)
@@ -10,6 +10,8 @@ class Prospect extends User
 {
 
     public static $group = "Annuaire";
+    public static $type = \App\User::TYPE_PROSPECT;
+
 
     public static function label()
     {
@@ -21,9 +23,4 @@ class Prospect extends User
         return "Prospect";
     }
 
-    public static function indexQuery(NovaRequest $request, $query)
-    {
-        return $query->where('type', 1);
-    }
-
 }
index b0fa75f8052cb54e9556fb9c3166a89e99214930..d35cfa4206d4d06633f09eb92063cda31c83707e 100644 (file)
@@ -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);
-    }
+
 
 }
index 3901448c8046d9a4e18a87b70f6862ee93eb6d95..d30ef1b57e14a01275083da103141412ba288df8 100644 (file)
@@ -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)
     {
index 03cad551989582fbca789f5e03d64d5890a87630..9c4a0be465fbbcc6c6ab68619c6c7daf2eeb3bb2 100644 (file)
@@ -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.
      *
index 69fb18ef44a25170be0025919c3fb32dbe9142ab..cb61ccc1c94f7f624406dd61d485503d6b03612d 100644 (file)
@@ -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);
 
+    }
 
 
 
index d2697a9803b2883e2304b3ce4d9d055d7612f68d..9df3459f01aa31a31f9bebbe75bd88387a953dfe 100644 (file)
@@ -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
+
         ];
     }
 
index 6a5bbb9072f6ad54e76699c8620d7c052bb36ca9..93cdeae416c49f43bca5dfaa022c321050cb0b20 100644 (file)
@@ -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 (file)
index 0000000..fda9c93
--- /dev/null
@@ -0,0 +1,32 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+class AddDiscoverUntilColumnToUsersTable extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::table('users', function (Blueprint $table) {
+            $table->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 (file)
index 0000000..e98130f
--- /dev/null
@@ -0,0 +1,32 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+class AddUnsubscribeColumnToUsersTable extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::table('users', function (Blueprint $table) {
+            $table->boolean('unsubscribed')->default(0);
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::table('users', function (Blueprint $table) {
+            $table->dropColumn('unsubscribed');
+        });
+    }
+}
index a9399a57aa3fcf6a8532a1ba55ed3ecf9f25fcca..cce51137826a3e7ae2e1115af1cca8b08ef22791 100644 (file)
@@ -19,7 +19,7 @@
                         <div class="truncated">
                             {!! $article->getTruncatedContent() !!}
                         </div>
-                        <div class="alert alert-warning">
+                        <div class="alert alert-warning mt-4">
                             Cet article est réservé aux abonnés ! Pour y accéder merci de vous connecter, ou
                             <a href="{{route('not-registered')}}" >cliquez ici pour découvrir nos formules d'abonnement.</a>
                         </div>
index 00cd5cddd75a1f177185e749dc5eef8f08645002..ca64a425619f73be201262796b658cad2d41fb15 100644 (file)
@@ -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');