From 3868797be9c1d4d0c5aa07b24a9a6cce28682d09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20Ioni=C8=9B=C4=83?= Date: Mon, 16 Oct 2023 07:21:15 +0100 Subject: [PATCH] feat: terms and newsletter (#299) * refactor registration validation rules * add terms and newsletter subscription checkboxes * add newsletter subscription * wip --------- Co-authored-by: Lupu Gheorghe <46172059+gheorghelupu17@users.noreply.github.com> --- app/Concerns/HasRole.php | 2 +- .../Auth/RegisteredUserController.php | 10 +- app/Http/Requests/RegistrationRequest.php | 30 ++-- app/Services/NewsletterService.php | 34 +++++ composer.json | 2 + composer.lock | 131 +++++++++++++++++- config/newsletter.php | 42 ++++++ lang/ro/validation.php | 5 +- resources/js/Pages/Auth/Register.vue | 3 + .../js/Pages/Auth/Registration/Step2.vue | 29 ++-- 10 files changed, 255 insertions(+), 33 deletions(-) create mode 100644 app/Services/NewsletterService.php create mode 100644 config/newsletter.php diff --git a/app/Concerns/HasRole.php b/app/Concerns/HasRole.php index 5aa8b7c6..772a1ee9 100644 --- a/app/Concerns/HasRole.php +++ b/app/Concerns/HasRole.php @@ -15,7 +15,7 @@ public function initializeHasRole(): void $this->casts['role'] = UserRole::class; } - private function hasRole(UserRole $role): bool + public function hasRole(UserRole $role): bool { return $this->role === $role; } diff --git a/app/Http/Controllers/Auth/RegisteredUserController.php b/app/Http/Controllers/Auth/RegisteredUserController.php index 52433361..1d27fffd 100644 --- a/app/Http/Controllers/Auth/RegisteredUserController.php +++ b/app/Http/Controllers/Auth/RegisteredUserController.php @@ -9,6 +9,7 @@ use App\Http\Controllers\Controller; use App\Http\Requests\RegistrationRequest; use App\Models\User; +use App\Services\NewsletterService; use Illuminate\Auth\Events\Registered; use Illuminate\Http\RedirectResponse; use Illuminate\Http\Request; @@ -44,12 +45,11 @@ public function store(RegistrationRequest $request): RedirectResponse 'email' => $attributes['user']['email'], 'password' => Hash::make($attributes['user']['password']), 'role' => $attributes['type'] === 'organization' ? UserRole::ADMIN : UserRole::USER, - ]); event(new Registered($user)); -// $user = User::find($user->id); - if ($user->role===UserRole::ADMIN) { + + if ($user->hasRole(UserRole::ADMIN)) { $attributes['ngo']['status'] = OrganizationStatus::draft; $organization = $user->organization()->create($attributes['ngo']); @@ -63,6 +63,10 @@ public function store(RegistrationRequest $request): RedirectResponse $user->save(); } + if ($attributes['subscribe']) { + NewsletterService::subscribe($user->email, $user->name); + } + Auth::login($user); return redirect()->route('register') diff --git a/app/Http/Requests/RegistrationRequest.php b/app/Http/Requests/RegistrationRequest.php index 3a2277d2..5bc99c1e 100644 --- a/app/Http/Requests/RegistrationRequest.php +++ b/app/Http/Requests/RegistrationRequest.php @@ -17,27 +17,29 @@ class RegistrationRequest extends FormRequest public function rules(): array { $rules = [ - 'type' => ['string', 'required'], - 'user' => ['array', 'required'], - 'user.name' => ['string', 'required'], - 'user.email' => ['email', 'required', 'unique:users,email'], - 'user.password' => ['string', 'required', 'confirmed'], + 'type' => ['required', 'string'], + 'terms' => ['required', 'accepted'], + 'subscribe' => ['boolean'], + 'user' => ['required', 'array'], + 'user.name' => ['required', 'string'], + 'user.email' => ['required', 'email', 'unique:users,email'], + 'user.password' => ['required', 'string', 'confirmed'], ]; if ($this->type === 'organization') { $rules = array_merge($rules, [ - 'ngo' => ['array', 'required'], - 'ngo.name' => ['string', 'required'], - 'ngo.description' => ['string', 'required', 'max:1000'], + 'ngo' => ['required', 'array'], + 'ngo.name' => ['required', 'string'], + 'ngo.description' => ['required', 'string', 'max:1000'], 'ngo.logo' => ['required', 'image'], 'ngo.statute' => ['required', 'file'], - 'ngo.street_address' => ['string', 'required'], - 'ngo.cif' => ['string', 'required', 'unique:organizations,cif', new ValidCIF], + 'ngo.street_address' => ['required', 'string'], + 'ngo.cif' => ['required', 'string', 'unique:organizations,cif', new ValidCIF], 'ngo.contact_email' => ['required', 'email'], - 'ngo.contact_phone' => ['string', 'required'], - 'ngo.contact_person' => ['string', 'required'], - 'ngo.domains' => ['array', 'required'], - 'ngo.counties' => ['array', 'required'], + 'ngo.contact_phone' => ['required', 'string'], + 'ngo.contact_person' => ['required', 'string'], + 'ngo.domains' => ['required', 'array'], + 'ngo.counties' => ['required', 'array'], 'ngo.volunteer' => ['boolean'], 'ngo.why_volunteer' => ['string', 'nullable', 'max:1000'], 'ngo.website' => ['string', 'nullable', 'url'], diff --git a/app/Services/NewsletterService.php b/app/Services/NewsletterService.php new file mode 100644 index 00000000..4f6ae24c --- /dev/null +++ b/app/Services/NewsletterService.php @@ -0,0 +1,34 @@ + $name, + ]; + + $options = [ + 'pending' => true, + ]; + + $response = rescue( + fn () => Newsletter::subscribe($email, $mergeFields, options: $options), + false + ); + + if (false !== $response) { + // TODO: check if email registered as user + // and assign subscriber badge if the + // user doesn't already have one. + } + + return $response; + } +} diff --git a/composer.json b/composer.json index a63f0ae5..6b642aa4 100644 --- a/composer.json +++ b/composer.json @@ -10,6 +10,7 @@ "php": "^8.1", "awcodes/filament-tiptap-editor": "^2.6", "camya/filament-title-with-slug": "^0.5.6", + "drewm/mailchimp-api": "^2.5", "filament/filament": "^2.17", "filament/spatie-laravel-media-library-plugin": "^2.17", "filament/spatie-laravel-translatable-plugin": "^2.17", @@ -23,6 +24,7 @@ "pxlrbt/filament-excel": "^1.1", "spatie/laravel-activitylog": "^4.7", "spatie/laravel-medialibrary": "^10.11", + "spatie/laravel-newsletter": "^5.1", "spatie/laravel-query-builder": "^5.3", "stevegrunwell/time-constants": "^1.1", "tightenco/ziggy": "^1.6" diff --git a/composer.lock b/composer.lock index 01c4a0b0..cd9b6c0f 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "5ed7d85f0d7c6b9488bc0da13e98bde8", + "content-hash": "4ac95c7c02290535af34d4c32725eae1", "packages": [ { "name": "akaunting/laravel-money", @@ -1239,6 +1239,54 @@ ], "time": "2023-08-10T19:36:49+00:00" }, + { + "name": "drewm/mailchimp-api", + "version": "v2.5.4", + "source": { + "type": "git", + "url": "https://github.com/drewm/mailchimp-api.git", + "reference": "c6cdfab4ca6ddbc3b260913470bd0a4a5cb84c7a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/drewm/mailchimp-api/zipball/c6cdfab4ca6ddbc3b260913470bd0a4a5cb84c7a", + "reference": "c6cdfab4ca6ddbc3b260913470bd0a4a5cb84c7a", + "shasum": "" + }, + "require": { + "ext-curl": "*", + "ext-json": "*", + "php": ">=5.3" + }, + "require-dev": { + "phpunit/phpunit": "7.0.*", + "vlucas/phpdotenv": "^2.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "DrewM\\MailChimp\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Drew McLellan", + "email": "drew.mclellan@gmail.com", + "homepage": "http://allinthehead.com/" + } + ], + "description": "Super-simple, minimum abstraction MailChimp API v3 wrapper", + "homepage": "https://github.com/drewm/mailchimp-api", + "support": { + "issues": "https://github.com/drewm/mailchimp-api/issues", + "source": "https://github.com/drewm/mailchimp-api/tree/master" + }, + "time": "2019-08-06T09:24:58+00:00" + }, { "name": "egulias/email-validator", "version": "4.0.1", @@ -6135,6 +6183,87 @@ ], "time": "2023-08-25T08:54:08+00:00" }, + { + "name": "spatie/laravel-newsletter", + "version": "5.1.1", + "source": { + "type": "git", + "url": "https://github.com/spatie/laravel-newsletter.git", + "reference": "825fb94ded624934eaaf2a0707e4ae2417f11a6c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/laravel-newsletter/zipball/825fb94ded624934eaaf2a0707e4ae2417f11a6c", + "reference": "825fb94ded624934eaaf2a0707e4ae2417f11a6c", + "shasum": "" + }, + "require": { + "php": "^8.1", + "spatie/laravel-package-tools": "^1.13" + }, + "require-dev": { + "drewm/mailchimp-api": "^2.5", + "guzzlehttp/guzzle": "^7.5|^7.2", + "mockery/mockery": "^1.4", + "orchestra/testbench": "^7.11|^8.0", + "pestphp/pest": "^1.20", + "phpstan/phpstan": "^1.9", + "phpunit/phpunit": "^9.5", + "spatie/mailcoach-sdk-php": "^1.0", + "spatie/ray": "^1.28" + }, + "suggest": { + "drewm/mailchimp-api": "For working with MailChimp", + "spatie/mailcoach-sdk-php": "For working with Mailcoach" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Spatie\\Newsletter\\NewsletterServiceProvider" + ], + "aliases": { + "Newsletter": "Spatie\\Newsletter\\Facades\\Newsletter" + } + } + }, + "autoload": { + "psr-4": { + "Spatie\\Newsletter\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Freek Van der Herten", + "email": "freek@spatie.be", + "homepage": "https://spatie.be", + "role": "Developer" + } + ], + "description": "Manage Mailcoach and MailChimp newsletters in Laravel", + "homepage": "https://github.com/spatie/laravel-newsletter", + "keywords": [ + "laravel", + "mailchimp", + "mailcoach", + "newsletter" + ], + "support": { + "issues": "https://github.com/spatie/laravel-newsletter/issues", + "source": "https://github.com/spatie/laravel-newsletter/tree/5.1.1" + }, + "funding": [ + { + "url": "https://spatie.be/open-source/support-us", + "type": "custom" + } + ], + "time": "2023-02-09T13:52:08+00:00" + }, { "name": "spatie/laravel-package-tools", "version": "1.16.1", diff --git a/config/newsletter.php b/config/newsletter.php new file mode 100644 index 00000000..114ada96 --- /dev/null +++ b/config/newsletter.php @@ -0,0 +1,42 @@ + env('NEWSLETTER_DRIVER', \Spatie\Newsletter\Drivers\MailChimpDriver::class), + + /* + * These arguments will be given to the driver. + */ + 'driver_arguments' => [ + 'api_key' => env('NEWSLETTER_API_KEY'), + + 'endpoint' => env('NEWSLETTER_ENDPOINT'), + ], + + /* + * The list name to use when no list name is specified in a method. + */ + 'default_list_name' => 'subscribers', + + 'lists' => [ + /* + * This key is used to identify this list. It can be used + * as the listName parameter provided in the various methods. + * + * You can set it to any string you want and you can add + * as many lists as you want. + */ + 'subscribers' => [ + /* + * When using the Mailcoach driver, this should be Email list UUID + * which is displayed in the Mailcoach UI + * + * When using the MailChimp driver, this should be a MailChimp list id. + * http://kb.mailchimp.com/lists/managing-subscribers/find-your-list-id. + */ + 'id' => env('NEWSLETTER_LIST_ID'), + ], + ], +]; diff --git a/lang/ro/validation.php b/lang/ro/validation.php index 173f2772..1de3baef 100644 --- a/lang/ro/validation.php +++ b/lang/ro/validation.php @@ -213,6 +213,9 @@ 'updated_at' => 'actualizat la', 'username' => 'nume de utilizator', 'year' => 'an', + 'user.name' => 'nume', + 'user.email' => 'email', + 'user.password' => 'parolă', 'end' => "Data finală perioada de donații", ], -]; +]; \ No newline at end of file diff --git a/resources/js/Pages/Auth/Register.vue b/resources/js/Pages/Auth/Register.vue index 09c3b147..5622e390 100644 --- a/resources/js/Pages/Auth/Register.vue +++ b/resources/js/Pages/Auth/Register.vue @@ -51,6 +51,8 @@ statute: '', }, type: '', + terms: false, + subscribe: false, }); const social = useForm({ @@ -135,6 +137,7 @@ onError: (error) => { /** Set active component in case of validation errors. */ if ( + error['terms'] || error['user.name'] || error['user.password'] || error['user.email'] || diff --git a/resources/js/Pages/Auth/Registration/Step2.vue b/resources/js/Pages/Auth/Registration/Step2.vue index ee7348b3..e6c3216b 100644 --- a/resources/js/Pages/Auth/Registration/Step2.vue +++ b/resources/js/Pages/Auth/Registration/Step2.vue @@ -53,20 +53,23 @@ /> - +
+ + +

+

-