diff --git a/app/Http/Controllers/Api/V1/CustomerController.php b/app/Http/Controllers/Api/V1/CustomerController.php index 7bee493..a46b8c1 100644 --- a/app/Http/Controllers/Api/V1/CustomerController.php +++ b/app/Http/Controllers/Api/V1/CustomerController.php @@ -60,20 +60,24 @@ class CustomerController extends Controller $customer = new Customer(); $customer->email = $email; $customer->save(); - $singleOptin = SingleOptin::where([['email', $email], ['brand_id', $brandId]])->first(); + $singleOptin = SingleOptin::query()->where([ + ['email', $email], ['brand_id', $brandId] + ])->first(); if ($singleOptin) { $singleOptin->delete(); } } else { // Récupère les infos s'ils existent déjà. - $CustomerInfo = CustomerInfo::where([['customer_id', $customer->id], ['brand_id', $brandId]])->first(); + $CustomerInfo = CustomerInfo::query()->where([ + ['customer_id', $customer->id], ['brand_id', $brandId] + ])->first(); if ($CustomerInfo) { return new StatusResource([ 'status' => 'KO', 'code' => 103, 'message' => 'User already registered on this site.' ]); } - } + }//end if $customerInfos = new CustomerInfo(); $customerInfos->firstname = ucfirst(strtolower($firstname)); @@ -549,7 +553,7 @@ class CustomerController extends Controller // Check si le customer ou l'optin simple existe avant de l'ajouter en optin simple. if ( - !SingleOptin::where([['email', $email], ['brand_id', $brandId]])->exists() && + !SingleOptin::query()->where([['email', $email], ['brand_id', $brandId]])->exists() && !CustomerInfo::join("customers", "customer_infos.customer_id", "=", "customers.id")->where([ ['brand_id', $brandId], ['email', $email] ])->exists() diff --git a/app/Http/Controllers/Api/V2/CustomerController.php b/app/Http/Controllers/Api/V2/CustomerController.php index 9ebbe2f..09368b4 100644 --- a/app/Http/Controllers/Api/V2/CustomerController.php +++ b/app/Http/Controllers/Api/V2/CustomerController.php @@ -14,6 +14,7 @@ use App\Jobs\UpdateCustomerLastConnection; use App\Models\Customer; use App\Models\Service; use App\Models\SingleOptin; +use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\ModelNotFoundException; use Illuminate\Http\JsonResponse; use Illuminate\Http\Resources\Json\JsonResource; @@ -47,8 +48,10 @@ class CustomerController extends Controller // * Delete Single optin if exists. /** @var \App\Models\SingleOptin|null $singleOptin */ - $singleOptin = SingleOptin::where('email', $data->email) - ->where('brand_id', $service->brand->id)->first(); + $singleOptin = SingleOptin::query()->where('email', $data->email) + ->whereHas('brand', function (Builder $q) use ($service) { + $q->where('id', $service->brand->id); + })->first(); if ($singleOptin) { $saved = $singleOptin->delete() && $saved; } diff --git a/app/Http/Controllers/Api/V2/OptinController.php b/app/Http/Controllers/Api/V2/OptinController.php index edfe4ca..d5c8415 100644 --- a/app/Http/Controllers/Api/V2/OptinController.php +++ b/app/Http/Controllers/Api/V2/OptinController.php @@ -31,9 +31,9 @@ class OptinController extends Controller } /** @var \App\Models\SingleOptin */ - $singleOptin = SingleOptin::where('email', $request->email) + $singleOptin = SingleOptin::query()->where('email', $request->email) ->whereHas('brand', function ($q) use ($service) { - $q->whereId($service->brand->id); + $q->where('id', $service->brand->id); })->firstOrNew(); if ($request->opt_in) { diff --git a/app/Http/Controllers/CustomerController.php b/app/Http/Controllers/CustomerController.php index 2f1a026..05b4482 100644 --- a/app/Http/Controllers/CustomerController.php +++ b/app/Http/Controllers/CustomerController.php @@ -9,6 +9,7 @@ use App\Models\Customer; use App\Models\CustomerInfo; use App\Models\CustomerLogin; use App\Models\SingleOptin; +use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Query\JoinClause; use Illuminate\Http\Request; use Illuminate\Support\Carbon; @@ -271,15 +272,16 @@ class CustomerController extends Controller } // ! Continue case CustomerExportType::singleOptin(): - SingleOptin::where('brand_id', $request->brand)->get() - ->map(function (SingleOptin $singleOptin) use ($w) { - $w->insertOne([ - 'lastname' => '', - 'firstname' => '', - 'email' => $singleOptin->email, - 'hashcode' => '' - ]); - }); + SingleOptin::query()->whereHas('brand', function (Builder $q) use ($request) { + $q->where('id', $request->brand); + })->get()->map(function (SingleOptin $singleOptin) use ($w) { + $w->insertOne([ + 'lastname' => '', + 'firstname' => '', + 'email' => $singleOptin->email, + 'hashcode' => $singleOptin->hashcode + ]); + }); break; default: throw new \Exception(sprintf('Unhandled CustomerExportType %s', $exportType->label)); diff --git a/app/Http/Controllers/SingleOptinController.php b/app/Http/Controllers/SingleOptinController.php index dab4b66..4bbca5a 100644 --- a/app/Http/Controllers/SingleOptinController.php +++ b/app/Http/Controllers/SingleOptinController.php @@ -3,6 +3,7 @@ namespace App\Http\Controllers; use App\Models\SingleOptin; +use Illuminate\Database\Eloquent\Builder; use Illuminate\Http\Request; use Illuminate\Support\Str; @@ -23,7 +24,9 @@ class SingleOptinController extends Controller $query = SingleOptin::query(); if ($request->brand) { - $query = $query->where('brand_id', '=', request()->brand); + $query = $query->whereHas('brand', function (Builder $q) { + $q->where('id', request()->brand); + }); } if ($request->search) { $this->searchQuery( diff --git a/app/Jobs/StatJob.php b/app/Jobs/StatJob.php index b4961e1..8ea412a 100644 --- a/app/Jobs/StatJob.php +++ b/app/Jobs/StatJob.php @@ -9,6 +9,7 @@ use App\Models\CustomerLogin; use App\Models\SingleOptin; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; +use Illuminate\Database\Eloquent\Builder; use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\Middleware\WithoutOverlapping; @@ -57,17 +58,29 @@ class StatJob implements ShouldQueue public function handle() { $stats = new BrandStat([ - 'active' => CustomerLogin::whereBrandId($this->brand->id) - ->whereDate('last_connection', '<', Carbon::now()->subMonths(6))->count(), - 'inactive' => CustomerLogin::whereBrandId($this->brand->id) + 'active' => CustomerLogin::query()->whereHas('brand', function (Builder $q) { + $q->where('id', $this->brand->id); + })->whereDate('last_connection', '<', Carbon::now()->subMonths(6))->count(), + 'inactive' => CustomerLogin::query()->whereHas('brand', function (Builder $q) { + $q->where('id', $this->brand->id); + }) ->whereDate('last_connection', '>', Carbon::now()->subMonths(6))->count(), - 'new_accounts' => CustomerLogin::whereBrandId($this->brand->id) + 'new_accounts' => CustomerLogin::query()->whereHas('brand', function (Builder $q) { + $q->where('id', $this->brand->id); + }) ->whereDate('created_at', '<', Carbon::now()->subMonths(6))->count(), - 'old_accounts' => CustomerLogin::whereBrandId($this->brand->id) + 'old_accounts' => CustomerLogin::query()->whereHas('brand', function (Builder $q) { + $q->where('id', $this->brand->id); + }) ->whereDate('created_at', '>', Carbon::now()->subMonths(6))->count(), - 'total_accounts' => CustomerLogin::whereBrandId($this->brand->id)->count(), - 'total_opt_in' => CustomerInfo::whereBrandId($this->brand->id) - ->whereOptIn(true)->count() + SingleOptin::whereBrandId($this->brand->id)->count() + 'total_accounts' => CustomerLogin::query()->whereHas('brand', function (Builder $q) { + $q->where('id', $this->brand->id); + })->count(), + 'total_opt_in' => CustomerInfo::query()->whereHas('brand', function (Builder $q) { + $q->where('id', $this->brand->id); + })->whereOptIn(true)->count() + SingleOptin::query()->whereHas('brand', function (Builder $q) { + $q->where('id', $this->brand->id); + })->count() ]); $stats->brand()->associate($this->brand); $stats->saveOrFail(); diff --git a/app/Lib/MigrateOldData.php b/app/Lib/MigrateOldData.php index 462edf6..5ce9ffe 100644 --- a/app/Lib/MigrateOldData.php +++ b/app/Lib/MigrateOldData.php @@ -10,6 +10,7 @@ use App\Models\CustomerLogin; use App\Models\SingleOptin; use Carbon\Exceptions\InvalidFormatException; use Database\migrations\LeGaulois2016Migration; +use Illuminate\Database\Eloquent\Builder; use Illuminate\Support\Carbon; use Illuminate\Support\Facades\File; use Illuminate\Support\Facades\Hash; @@ -85,8 +86,10 @@ class MigrateOldData extends LeGaulois2016Migration // * Just save Single optin. if (empty($first_name) && empty($last_name)) { - $sglOptin = SingleOptin::where('email', strtolower($email)) - ->where('brand_id', $this->brand->id)->firstOrNew(); + $sglOptin = SingleOptin::query()->where('email', strtolower($email)) + ->whereHas('brand', function (Builder $q) { + $q->where('id', $this->brand->id); + })->firstOrNew(); $sglOptin->email = strtolower($email); $sglOptin->brand_id = $this->brand->id; $sglOptin->save(); diff --git a/app/Models/SingleOptin.php b/app/Models/SingleOptin.php index 526ad5e..8cf0a78 100644 --- a/app/Models/SingleOptin.php +++ b/app/Models/SingleOptin.php @@ -4,11 +4,33 @@ namespace App\Models; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; +use Illuminate\Support\Str; class SingleOptin extends Model { use HasFactory; + /** + * The primary key for the model. + * + * @var string + */ + protected $primaryKey = 'hashcode'; + + /** + * The "type" of the primary key ID. + * + * @var string + */ + protected $keyType = 'uuid'; + + /** + * Indicates if the IDs are auto-incrementing. + * + * @var boolean + */ + public $incrementing = false; + /** * The attributes that are mass assignable. * @@ -18,6 +40,18 @@ class SingleOptin extends Model 'email' ]; + /** + * Perform any actions required after the model boots. + * + * @return void + */ + protected static function booted() + { + static::creating(function (self $model) { + $model->hashcode = Str::uuid(); + }); + } + // * RELATIONS /** diff --git a/database/migrations/2023_06_23_171318_add_change_single_optin_to_use_hashcode.php b/database/migrations/2023_06_23_171318_add_change_single_optin_to_use_hashcode.php new file mode 100644 index 0000000..9c174fc --- /dev/null +++ b/database/migrations/2023_06_23_171318_add_change_single_optin_to_use_hashcode.php @@ -0,0 +1,49 @@ +uuid('hashcode')->comment('Single optin hashcode')->after('id'); + }); + DB::transaction(function () { + DB::table('single_optins')->get()->each(function (object $single_optin) { + DB::table('single_optins')->where('id', $single_optin->id)->update([ + 'hashcode' => Str::uuid() + ]); + }); + }); + Schema::table('single_optins', function (Blueprint $table) { + $table->uuid('hashcode')->comment('Single optin hashcode')->after('id') + ->unique()->change(); + $table->dropColumn('id'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('single_optins', function (Blueprint $table) { + $table->id()->after('hashcode'); + }); + Schema::table('single_optins', function (Blueprint $table) { + $table->dropColumn('hashcode'); + }); + } +} diff --git a/tests/CRM/ApiV2/CustomerTest.php b/tests/CRM/ApiV2/CustomerTest.php index 1c1c6fa..ba84bb4 100644 --- a/tests/CRM/ApiV2/CustomerTest.php +++ b/tests/CRM/ApiV2/CustomerTest.php @@ -683,7 +683,7 @@ class CustomerTest extends ApiBase // * Delete Single optin if exists. /** @var \App\Models\SingleOptin|null $singleOptin */ - $singleOptin = SingleOptin::where('email', $data['email']) + $singleOptin = SingleOptin::query()->where('email', $data['email']) ->whereHas('brand', function ($q) use ($brand) { $q->where('brands.id', '=', $brand->id); })->first(); diff --git a/tests/CRM/ApiV2/SingleOptinTest.php b/tests/CRM/ApiV2/SingleOptinTest.php index f1ec95c..36d7c55 100644 --- a/tests/CRM/ApiV2/SingleOptinTest.php +++ b/tests/CRM/ApiV2/SingleOptinTest.php @@ -32,7 +32,7 @@ class SingleOptinTest extends ApiBase $json = $response->decodeResponseJson(); $this->assertApiResponseStatusIs($json, ApiStatus::OK()); $this->assertTrue( - SingleOptin::where('email', 'singleoptin@hotmail.fr')->exists(), + SingleOptin::query()->where('email', 'singleoptin@hotmail.fr')->exists(), 'Single optin should have been set for email "singleoptin@hotmail.fr"' ); } @@ -54,7 +54,7 @@ class SingleOptinTest extends ApiBase $json = $response->decodeResponseJson(); $this->assertApiResponseStatusIs($json, ApiStatus::OK()); $this->assertFalse( - SingleOptin::where('email', 'singleoptin@hotmail.fr')->exists(), + SingleOptin::query()->where('email', 'singleoptin@hotmail.fr')->exists(), 'Single optin should have been removed for email "singleoptin@hotmail.fr"' ); } @@ -71,7 +71,7 @@ class SingleOptinTest extends ApiBase $this->storeCustomer($service); // * Make sure a single optin exists. - $singleOptin = SingleOptin::whereEmail('singleoptin@hotmail.fr')->firstOrNew(); + $singleOptin = SingleOptin::query()->where('email', 'singleoptin@hotmail.fr')->firstOrNew(); $singleOptin->brand()->associate($service->brand); $singleOptin->email = 'singleoptin@hotmail.fr'; $singleOptin->saveOrFail(); diff --git a/tests/Client/CrmClientV2CustomerTest.php b/tests/Client/CrmClientV2CustomerTest.php index 1b19a55..e800bda 100644 --- a/tests/Client/CrmClientV2CustomerTest.php +++ b/tests/Client/CrmClientV2CustomerTest.php @@ -507,7 +507,7 @@ class CrmClientV2CustomerTest extends CrmClientTester // * Delete Single optin if exists. /** @var \App\Models\SingleOptin|null $singleOptin */ - $singleOptin = SingleOptin::where('email', $data['email']) + $singleOptin = SingleOptin::query()->where('email', $data['email']) ->whereHas('brand', function ($q) use ($brand) { $q->where('brands.id', '=', $brand->id); })->first(); diff --git a/tests/Client/CrmClientV2SingleOptinTest.php b/tests/Client/CrmClientV2SingleOptinTest.php index 7b33f37..0732781 100644 --- a/tests/Client/CrmClientV2SingleOptinTest.php +++ b/tests/Client/CrmClientV2SingleOptinTest.php @@ -24,14 +24,14 @@ class CrmClientV2SingleOptinTest extends CrmClientTester { // Set single optin and check. $this->assertTrue(SingleOptin::setStatus('singleoptinrandom@gmail.com', true)); - $this->assertTrue(ModelsSingleOptin::where('email', 'singleoptinrandom@gmail.com')->exists()); + $this->assertTrue(ModelsSingleOptin::query()->where('email', 'singleoptinrandom@gmail.com')->exists()); // Set single optin again should not fail. $this->assertTrue(CrmApiV2::setStatus('singleoptinrandom@gmail.com', true)); // Remove single optin test and check. $this->assertTrue(SingleOptin::setStatus('singleoptinrandom@gmail.com', false)); - $this->assertTrue(!ModelsSingleOptin::where('email', 'singleoptinrandom@gmail.com')->exists()); + $this->assertTrue(!ModelsSingleOptin::query()->where('email', 'singleoptinrandom@gmail.com')->exists()); } /**