diff --git a/.gitignore b/.gitignore
index af8c675..99d37f1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,3 +6,4 @@ composer.lock
mix-manifest.json
package-lock.json
yarn.lock
+.idea/*
diff --git a/README.md b/README.md
index fe9c6ec..c8b6335 100644
--- a/README.md
+++ b/README.md
@@ -37,13 +37,24 @@ php artisan vendor:publish --tag="campaign-monitor-config"
## Usage
-Create your Statamic [forms](https://statamic.dev/forms#content) as usual. Don't forget to add the consent field to your blueprint.
+Create your Statamic [forms](https://statamic.dev/forms#content) as usual. When editing the form you'll see a "Campaign Monitor Integration" section where you can configure if and how that form integrates with Campaign Monitor.
+
+Don't forget to add the consent field to your blueprint.
+
+You can also manage if new users are added a list using the dedicated settings view in the control panel.
*Configuration in the Control Panel:*
![control panel](https://raw.githubusercontent.com/statamic-rad-pack/campaign-monitor/main/images/config.png)
+### Data storage
+
+Any user related settings are stored by default in `resources/campaign_monitor.yaml`.
+
+If you want to change this or use a different data store, you can bind `\StatamicRadPack\Mailchimp\UserConfig::class` in your app service provider. You should modify the `getSavedSettings`, `save`, and `exists` methods according to your requirements.
+
+
## Testing
Run the tests with:
diff --git a/composer.json b/composer.json
index b02082e..17ed707 100644
--- a/composer.json
+++ b/composer.json
@@ -14,13 +14,14 @@
"require": {
"php": "^8.1",
"bashy/laravel-campaignmonitor": "^6.0",
- "edalzell/forma": "^3.0",
"laravel/framework": "^10.25.0 || ^11.0",
"pixelfear/composer-dist-plugin": "^0.1",
- "statamic/cms": "^4.0 || ^5.0"
+ "statamic/cms": "^5.18",
+ "stillat/proteus": "^4.0"
},
"require-dev": {
"jasonmccreary/laravel-test-assertions": "^2.0",
+ "laravel/pint": "^1.17",
"mockery/mockery": "^1.3.1",
"orchestra/testbench": "^7.0 || ^8.0 || ^9.0",
"phpunit/phpunit": "^9.0 || ^10.0"
@@ -54,6 +55,5 @@
"description": "Campaign Monitor addon",
"name": "Campaign Monitor"
}
- },
- "minimum-stability": "alpha"
+ }
}
diff --git a/config/campaign-monitor.php b/config/campaign-monitor.php
index f2f475b..fb9def5 100644
--- a/config/campaign-monitor.php
+++ b/config/campaign-monitor.php
@@ -3,83 +3,6 @@
return [
'api_key' => env('CAMPAIGNMONITOR_API_KEY'),
-
- 'client_id' => env('CAMPAIGNMONITOR_CLIENT_ID'),
- /*
- * Set to `true` to add new user registrations to a Campaign Monitor list
- */
- 'add_new_users' => false,
-
- 'users' => [
- /*
- * A Campaign Monitor List ID.
- *
- */
- 'list_id' => null,
-
- /*
- * Set to `true` to require consent before subscribing someone
- * Default: `true`
- */
- 'check_consent' => true,
-
- /*
- * Field name used to check for consent.
- * Default: 'consent'
- */
- 'consent_field' => 'consent',
-
- /*
- * Set to `true` to require consent before SMS subscribing someone
- * Default: `true`
- */
- 'check_consent_sms' => true,
-
- /*
- * Field name used to check for consent.
- * Default: 'consent_sms'
- */
- 'consent_field_sms' => 'consent_sms',
-
- /*
- * Store information about your contacts with custom fields.
- */
- 'custom_fields' => [
- // [
- // /*
- // * The Campaign Monitor key
- // */
- // 'key'=> null,
-
- // /*
- // * Blueprint field name to use for the merge field
- // */
- // 'field_name' => null,
- // ],
- ],
-
- /*
- * Field that contains the mobile number
- * Default: 'mobile'
- */
- 'mobile_field' => 'mobile',
-
- /*
- * Field that contains the name
- * Default: 'name'
- */
- 'name_field' => 'name',
-
- /*
- * Field that contains the primary email address
- * Default: 'email'
- */
- 'primary_email_field' => 'email',
- ],
-
- /*
- * The form submissions to add to your Campaign Monitor lists
- */
- 'forms' => [],
+ 'client_id' => env('CAMPAIGNMONITOR_CLIENT_ID'),
];
diff --git a/images/config.png b/images/config.png
index 10d51b3..a0b31b4 100644
Binary files a/images/config.png and b/images/config.png differ
diff --git a/resources/blueprints/config.yaml b/resources/blueprints/config.yaml
index 30c80ac..75bf070 100644
--- a/resources/blueprints/config.yaml
+++ b/resources/blueprints/config.yaml
@@ -1,133 +1,4 @@
tabs:
- forms:
- display: 'Forms'
- sections:
- -
- fields:
- -
- handle: forms
- field:
- fields:
- -
- handle: form
- field:
- display: Form
- type: form
- max_items: 1
- mode: select
- width: 33
- -
- handle: list_id
- field:
- display: 'List ID'
- type: campaign_monitor_list
- mode: select
- max_items: 1
- width: 33
- -
- handle: name_field
- field:
- display: 'Name Field'
- type: campaign_monitor_form_fields
- max_items: 1
- default: name
- width: 33
- -
- handle: primary_email_field
- field:
- display: 'Email Field'
- type: campaign_monitor_form_fields
- max_items: 1
- default: email
- width: 33
- -
- handle: check_consent
- field:
- display: 'Check Consent?'
- type: toggle
- width: 33
- default: false
- -
- handle: consent_field
- field:
- display: 'Consent Field'
- type: campaign_monitor_form_fields
- default: consnet
- width: 33
- if:
- check_consent: true
- -
- handle: spacer_field
- field:
- display: 'Consent Field'
- type: spacer
- width: 33
- if:
- check_consent: false
- -
- handle: mobile_field
- field:
- display: 'Mobile Number Field'
- type: campaign_monitor_form_fields
- default: mobile
- width: 33
- -
- handle: check_consent_sms
- field:
- display: 'Check Consent to SMS?'
- type: toggle
- width: 33
- default: false
- -
- handle: consent_field_sms
- field:
- display: 'SMS Consent Field'
- type: campaign_monitor_form_fields
- default: consent_sms
- width: 33
- if:
- check_consent_sms: true
- -
- handle: spacer_field_sms
- field:
- display: 'Consent Field'
- type: spacer
- width: 33
- if:
- check_consent_sms: false
- -
- handle: custom_fields
- field:
- fields:
- -
- handle: field_name
- field:
- input_type: text
- display: Form Field
- type: campaign_monitor_form_fields
- icon: text
- listable: hidden
- -
- handle: key
- field:
- input_type: text
- display: 'Custom Field'
- type: campaign_monitor_custom_fields
- max_items: 1
- icon: text
- listable: hidden
- mode: table
- reorderable: true
- display: 'Custom Fields'
- type: grid
- icon: grid
- add_row: 'Add Custom Field'
- listable: hidden
- display: ' '
- type: grid
- mode: stacked
- add_row: 'Add Form'
- instructions: 'Add the forms you want to process Campaign Monitor submissions for.'
users:
display: 'Users'
sections:
@@ -155,7 +26,7 @@ tabs:
handle: name_field
field:
display: 'Name Field'
- type: campaign_monitor_form_fields
+ type: campaign_monitor_user_fields
max_items: 1
default: name
width: 33
@@ -169,7 +40,7 @@ tabs:
handle: primary_email_field
field:
display: 'Email Field'
- type: campaign_monitor_form_fields
+ type: campaign_monitor_user_fields
max_items: 1
default: email
width: 33
@@ -184,7 +55,7 @@ tabs:
handle: consent_field
field:
display: 'Consent Field'
- type: campaign_monitor_form_fields
+ type: campaign_monitor_user_fields
default: consnet
width: 33
if:
@@ -201,7 +72,7 @@ tabs:
handle: mobile_field
field:
display: 'Mobile Number Field'
- type: campaign_monitor_form_fields
+ type: campaign_monitor_user_fields
default: mobile
width: 33
-
@@ -215,7 +86,7 @@ tabs:
handle: consent_field_sms
field:
display: 'SMS Consent Field'
- type: campaign_monitor_form_fields
+ type: campaign_monitor_user_fields
default: consent_sms
width: 33
if:
@@ -237,7 +108,7 @@ tabs:
field:
input_type: text
display: Form Field
- type: campaign_monitor_form_fields
+ type: campaign_monitor_user_fields
icon: text
listable: hidden
-
@@ -257,12 +128,12 @@ tabs:
add_row: 'Add Custom Field'
listable: hidden
display: ' '
- instructions: 'Add the forms you want to process Campaign Monitor submissions for.'
type: grid
mode: stacked
max_rows: 1
min_rows: 1
reorderable: false
+ fullscreen: false
if:
add_new_users: 'equals true'
credentials:
diff --git a/resources/js/components/fieldtypes/CustomFieldsFieldtype.vue b/resources/js/components/fieldtypes/CustomFieldsFieldtype.vue
index 6d5c4bf..ebf9d0b 100644
--- a/resources/js/components/fieldtypes/CustomFieldsFieldtype.vue
+++ b/resources/js/components/fieldtypes/CustomFieldsFieldtype.vue
@@ -42,7 +42,12 @@ export default {
computed: {
key() {
- let matches = this.namePrefix.match(/([a-z]*?)\[(.*?)\]/);
+ let matches = this.namePrefix.match(/([a-z_]*?)\[(.*?)\]/);
+
+ if (matches[1] == 'campaign_monitor') { // form page
+ return 'campaign_monitor.settings.list_id.0';
+ }
+
return matches[0].replace('[', '.').replace(']', '.') + 'list_id.0';
},
@@ -62,7 +67,8 @@ export default {
.get(cp_url(`/campaign-monitor/custom-fields/${this.list}`))
.then(response => {
this.fields = response.data;
- });
+ })
+ .catch(() => { this.fields = []; });
}
}
};
diff --git a/resources/js/components/fieldtypes/FormFieldsFieldtype.vue b/resources/js/components/fieldtypes/FormFieldsFieldtype.vue
index 30af343..38a4769 100644
--- a/resources/js/components/fieldtypes/FormFieldsFieldtype.vue
+++ b/resources/js/components/fieldtypes/FormFieldsFieldtype.vue
@@ -42,16 +42,8 @@ export default {
computed: {
form() {
- let key = 'forms.' + this.row + '.form.0' ;
-
- return data_get(this.$store.state.publish[this.storeName].values, key)
+ return StatamicConfig.urlPath.split('/')[1] ?? '';
},
-
- row() {
- let matches = this.namePrefix.match(/\[(.*?)\]/);
-
- return matches[1];
- }
},
mounted() {
@@ -66,7 +58,8 @@ export default {
.get(cp_url(`/campaign-monitor/form-fields/${this.form}`))
.then(response => {
this.fields = response.data;
- });
+ })
+ .catch(() => { this.fields = []; });
}
}
};
diff --git a/resources/js/components/fieldtypes/UserFieldsFieldtype.vue b/resources/js/components/fieldtypes/UserFieldsFieldtype.vue
index 4bf07df..dc612e3 100644
--- a/resources/js/components/fieldtypes/UserFieldsFieldtype.vue
+++ b/resources/js/components/fieldtypes/UserFieldsFieldtype.vue
@@ -37,7 +37,8 @@ export default {
.get(cp_url(`/campaign-monitor/user-fields`))
.then(response => {
this.fields = response.data;
- });
+ })
+ .catch(() => { this.fields = []; });
}
}
};
diff --git a/resources/views/cp/config.blade.php b/resources/views/cp/config.blade.php
new file mode 100644
index 0000000..f71dc72
--- /dev/null
+++ b/resources/views/cp/config.blade.php
@@ -0,0 +1,12 @@
+@extends('statamic::layout')
+@section('title', __('Manage Campaign Monitor Settings'))
+
+@section('content')
+
+@stop
\ No newline at end of file
diff --git a/routes/cp.php b/routes/cp.php
index 67ac707..8ab6f63 100644
--- a/routes/cp.php
+++ b/routes/cp.php
@@ -1,12 +1,13 @@
prefix('campaign-monitor')->group(function () {
- Route::get('form-fields/{form}', [GetFormFieldsController::class, '__invoke'])->name('form-fields');
- Route::get('custom-fields/{list}', [GetCustomFieldsController::class, '__invoke'])->name('custom-fields');
- Route::get('user-fields', [GetUserFieldsController::class, '__invoke'])->name('user-fields');
+ Route::get('config', [Controllers\ConfigController::class, 'edit'])->name('config.edit');
+ Route::post('config', [Controllers\ConfigController::class, 'update'])->name('config.update');
+
+ Route::get('form-fields/{form}', [Controllers\GetFormFieldsController::class, '__invoke'])->name('form-fields');
+ Route::get('custom-fields/{list}', [Controllers\GetCustomFieldsController::class, '__invoke'])->name('custom-fields');
+ Route::get('user-fields', [Controllers\GetUserFieldsController::class, '__invoke'])->name('user-fields');
});
diff --git a/src/Fieldtypes/CampaignMonitorList.php b/src/Fieldtypes/CampaignMonitorList.php
index f12d018..8f82a9a 100644
--- a/src/Fieldtypes/CampaignMonitorList.php
+++ b/src/Fieldtypes/CampaignMonitorList.php
@@ -4,14 +4,13 @@
use Bashy\CampaignMonitor\Facades\CampaignMonitor;
use Statamic\Fieldtypes\Relationship;
-use Statamic\Support\Arr;
class CampaignMonitorList extends Relationship
{
public function getIndexItems($request)
{
$lists = CampaignMonitor::clients(config('campaign-monitor.client_id'))->get_lists();
-
+
return collect($lists->response ?? [])
->map(function ($list) {
return ['id' => $list->ListID, 'title' => $list->Name];
@@ -27,7 +26,7 @@ protected function toItemArray($id)
if (! $list = CampaignMonitor::lists($id)->get()?->response ?? false) {
return [];
}
-
+
return [
'id' => $list->ListID,
'title' => $list->Title,
diff --git a/src/Http/Controllers/ConfigController.php b/src/Http/Controllers/ConfigController.php
index f32b1d4..8e132b6 100644
--- a/src/Http/Controllers/ConfigController.php
+++ b/src/Http/Controllers/ConfigController.php
@@ -2,33 +2,53 @@
namespace StatamicRadPack\CampaignMonitor\Http\Controllers;
-use Edalzell\Forma\ConfigController as BaseController;
+use Illuminate\Http\Request;
use Illuminate\Support\Arr;
+use Illuminate\Support\Facades\Auth;
+use Statamic\Facades\Blueprint;
+use Statamic\Facades\YAML;
+use Statamic\Fields\Blueprint as BlueprintContract;
+use Statamic\Http\Controllers\CP\CpController;
+use StatamicRadpack\CampaignMonitor\UserConfig;
-class ConfigController extends BaseController
+class ConfigController extends CpController
{
- protected function postProcess(array $values): array
+ public function edit()
{
- $userConfig = Arr::get($values, 'users');
+ abort_if(Auth::user()->cant('manage campaign-monitor settings'), 403);
- return array_merge(
- $values,
- ['users' => $userConfig[0]]
- );
+ $values = config('campaign-monitor');
+ $values['users'] = [$values['users']];
+
+ $blueprint = $this->getBlueprint();
+
+ $fields = $blueprint->fields()->addValues($values)->preProcess();
+
+ return view('campaign-monitor::cp.config', [
+ 'blueprint' => $blueprint->toPublishArray(),
+ 'values' => $fields->values(),
+ 'meta' => $fields->meta(),
+ ]);
}
- protected function preProcess(string $handle): array
+ public function update(Request $request)
{
- $config = config($handle);
+ abort_if(Auth::user()->cant('manage campaign-monitor settings'), 403);
+
+ $fields = $this->getBlueprint()->fields()->addValues($request->all());
- return array_merge(
- $config,
- ['users' => [Arr::get($config, 'users', [])]]
- );
+ $fields->validate();
+
+ $values = $fields->process()->values()->all();
+ $values['users'] = $values['users'][0];
+
+ UserConfig::load(Arr::only($values, ['add_new_users', 'users']))->save();
+
+ return response()->json(['message' => __('Settings updated')]);
}
-
- public static function cpIcon()
+
+ private function getBlueprint(): BlueprintContract
{
- return '';
+ return Blueprint::make()->setContents(YAML::file(__DIR__.'/../../../resources/blueprints/config.yaml')->parse());
}
}
diff --git a/src/Http/Controllers/GetCustomFieldsController.php b/src/Http/Controllers/GetCustomFieldsController.php
index d01cfbd..a9ec983 100644
--- a/src/Http/Controllers/GetCustomFieldsController.php
+++ b/src/Http/Controllers/GetCustomFieldsController.php
@@ -3,7 +3,6 @@
namespace StatamicRadPack\CampaignMonitor\Http\Controllers;
use Bashy\CampaignMonitor\Facades\CampaignMonitor;
-use Illuminate\Support\Arr;
use Statamic\Http\Controllers\Controller;
class GetCustomFieldsController extends Controller
@@ -14,6 +13,7 @@ public function __invoke(string $list): array
return collect($fields->response ?? [])
->map(fn ($mergeField) => ['id' => $mergeField->Key, 'label' => $mergeField->FieldName])
+ ->values()
->all();
}
}
diff --git a/src/Migrators/ConfigToFormData.php b/src/Migrators/ConfigToFormData.php
new file mode 100644
index 0000000..a3aa2c1
--- /dev/null
+++ b/src/Migrators/ConfigToFormData.php
@@ -0,0 +1,27 @@
+merge([
+ 'campaign_monitor' => [
+ 'enabled' => true,
+ 'settings' => Arr::except($config, ['form', 'id']),
+ ],
+ ])->saveQuietly();
+ }
+}
diff --git a/src/ServiceProvider.php b/src/ServiceProvider.php
index 552faf5..2d666db 100644
--- a/src/ServiceProvider.php
+++ b/src/ServiceProvider.php
@@ -2,18 +2,20 @@
namespace StatamicRadPack\CampaignMonitor;
-use Edalzell\Forma\Forma;
use Statamic\Events\SubmissionCreated;
use Statamic\Events\UserRegistered;
+use Statamic\Facades\CP\Nav;
+use Statamic\Facades\Form;
+use Statamic\Facades\Permission;
use Statamic\Providers\AddonServiceProvider;
use Statamic\Support\Arr;
use StatamicRadPack\CampaignMonitor\Fieldtypes\CampaignMonitorCustomFields;
use StatamicRadPack\CampaignMonitor\Fieldtypes\CampaignMonitorFormFields;
use StatamicRadPack\CampaignMonitor\Fieldtypes\CampaignMonitorList;
use StatamicRadPack\CampaignMonitor\Fieldtypes\CampaignMonitorUserFields;
-use StatamicRadPack\CampaignMonitor\Http\Controllers\ConfigController;
use StatamicRadPack\CampaignMonitor\Listeners\AddFromSubmission;
use StatamicRadPack\CampaignMonitor\Listeners\AddFromUser;
+use Stillat\Proteus\Support\Facades\ConfigWriter;
class ServiceProvider extends AddonServiceProvider
{
@@ -43,25 +45,47 @@ public function boot()
{
parent::boot();
- Forma::add('statamic-rad-pack/campaign-monitor', ConfigController::class);
+ Permission::extend(function () {
+ Permission::register('manage campaign-monitor settings')
+ ->label(__('Manage Campaign Monitor Settings'));
+ });
+
+ Nav::extend(fn ($nav) => $nav
+ ->content(__('Campaign Monitor'))
+ ->section(__('Settings'))
+ ->can('manage campaign-monitor settings')
+ ->route('campaign-monitor.config.edit')
+ ->icon('')
+ );
+
+ $this->addFormConfigFields();
$this->app->booted(function () {
+ $this->migrateToFormConfig();
+ $this->migrateUserToYaml();
+
$this->addFormsToNewsletterConfig();
});
}
private function addFormsToNewsletterConfig()
{
- $lists = collect(config('campaign-monitor.forms'))
+ $lists = Form::all()
->flatMap(function ($form) {
- if (! $handle = Arr::get($form, 'form')) {
+ $data = $form->get('campaign_monitor', []);
+
+ if (! $enabled = Arr::get($data, 'enabled')) {
+ return [];
+ }
+
+ if (! $data = Arr::get($data, 'settings', [])) {
return [];
}
return [
- $handle => Arr::removeNullValues([
- 'id' => Arr::get($form, 'list_id'),
- 'marketing_permissions' => collect(Arr::get($form, 'marketing_permissions_field_ids'))
+ $form->handle() => Arr::removeNullValues([
+ 'id' => Arr::get($data, 'list_id'),
+ 'marketing_permissions' => collect(Arr::get($data, 'marketing_permissions_field_ids'))
->filter()
->flatMap(fn ($value) => [$value['field_name'] => $value['id']])
->all(),
@@ -74,4 +98,221 @@ private function addFormsToNewsletterConfig()
config(['campaign-monitor.lists' => $lists]);
}
+
+ private function addFormConfigFields()
+ {
+ Form::appendConfigFields('*', __('Campaign Monitor Integration'), [
+ 'campaign_monitor' => [
+ 'handle' => 'campaign_monitor',
+ 'type' => 'group',
+ 'display' => ' ',
+ 'fullscreen' => false,
+ 'border' => false,
+ 'fields' => [
+ [
+ 'handle' => 'enabled',
+ 'field' => [
+ 'type' => 'toggle',
+ 'display' => __('Enabled'),
+ 'width' => 100,
+ ],
+ ],
+
+ [
+ 'handle' => 'settings',
+ 'field' => [
+ 'type' => 'group',
+ 'display' => ' ',
+ 'width' => 100,
+ 'fullscreen' => false,
+ 'show_when' => ['enabled' => true],
+ 'fields' => [
+
+ [
+ 'handle' => 'list_id',
+ 'field' => [
+ 'type' => 'campaign_monitor_list',
+ 'max_items' => 1,
+ 'mode' => 'select',
+ 'display' => __('List ID'),
+ 'width' => 33,
+ ],
+ ],
+
+ [
+ 'handle' => 'name_field',
+ 'field' => [
+ 'type' => 'campaign_monitor_form_fields',
+ 'max_items' => 1,
+ 'default' => 'name',
+ 'display' => __('Name Field'),
+ 'width' => 33,
+ ],
+ ],
+
+ [
+ 'handle' => 'primary_email_field',
+ 'field' => [
+ 'type' => 'campaign_monitor_form_fields',
+ 'max_items' => 1,
+ 'default' => 'email',
+ 'display' => __('Email Field'),
+ 'width' => 33,
+ ],
+ ],
+
+ [
+ 'handle' => 'check_consent',
+ 'field' => [
+ 'type' => 'toggle',
+ 'display' => __('Check Consent?'),
+ 'width' => 33,
+ 'default' => false,
+ ],
+ ],
+
+ [
+ 'handle' => 'consent_field',
+ 'field' => [
+ 'type' => 'campaign_monitor_form_fields',
+ 'default' => 'consent',
+ 'max_items' => 1,
+ 'display' => __('Consent Field'),
+ 'width' => 33,
+ 'if' => ['check_consent' => true],
+ ],
+ ],
+
+ [
+ 'handle' => 'spacer_field',
+ 'field' => [
+ 'type' => 'spacer',
+ 'width' => 33,
+ 'if' => ['check_consent' => false],
+ ],
+ ],
+
+ [
+ 'handle' => 'mobile_field',
+ 'field' => [
+ 'type' => 'campaign_monitor_form_fields',
+ 'default' => 'mobile',
+ 'max_items' => 1,
+ 'display' => __('Mobile Number Field'),
+ 'width' => 33,
+ ],
+ ],
+
+ [
+ 'handle' => 'check_consent_sms',
+ 'field' => [
+ 'type' => 'toggle',
+ 'display' => __('Check Consent to SMS?'),
+ 'width' => 33,
+ 'default' => false,
+ ],
+ ],
+
+ [
+ 'handle' => 'consent_field_sms',
+ 'field' => [
+ 'type' => 'campaign_monitor_form_fields',
+ 'default' => 'consent_sms',
+ 'max_items' => 1,
+ 'display' => __('SMS Consent Field'),
+ 'width' => 33,
+ 'if' => ['check_consent_sms' => true],
+ ],
+ ],
+
+ [
+ 'handle' => 'spacer_field_sms',
+ 'field' => [
+ 'type' => 'spacer',
+ 'width' => 33,
+ 'if' => ['check_consent_sms' => false],
+ ],
+ ],
+
+ [
+ 'handle' => 'custom_fields',
+ 'field' => [
+ 'type' => 'grid',
+ 'mode' => 'table',
+ 'reorderable' => true,
+ 'listable' => 'hidden',
+ 'display' => __('Custom Fields'),
+ 'width' => 100,
+ 'add_row' => __('Add Custom Field'),
+ 'fields' => [
+
+ [
+ 'handle' => 'field_name',
+ 'field' => [
+ 'type' => 'campaign_monitor_form_fields',
+ 'display' => __('Form Field'),
+ 'width' => 33,
+ ],
+ ],
+
+ [
+ 'handle' => 'key',
+ 'field' => [
+ 'type' => 'campaign_monitor_custom_fields',
+ 'display' => __('Custom Field'),
+ 'max_items' => 1,
+ 'width' => 33,
+ ],
+ ],
+
+ ],
+ ],
+ ],
+
+ ],
+
+ ],
+
+ ],
+
+ ],
+ ],
+ ]);
+ }
+
+ private function migrateToFormConfig()
+ {
+ if (! $forms = config('campaign-monitor.forms')) {
+ return;
+ }
+
+ foreach ($forms as $config) {
+ (new Migrators\ConfigToFormData)->handle($config);
+ }
+
+ ConfigWriter::edit('campaign-monitor')->remove('forms')->save();
+ }
+
+ private function migrateUserToYaml()
+ {
+ $config = UserConfig::load();
+
+ if ($config->exists()) {
+ $config = $config->config();
+ config(['campaign-monitor.add_new_users' => $config['add_new_users'] ?? false]);
+ config(['campaign-monitor.users' => $config['users'] ?? []]);
+
+ return;
+ }
+
+ UserConfig::load([
+ 'add_new_users' => config('campaign-monitor.add_new_users', false),
+ 'users' => config('campaign-monitor.users', []),
+ ])->save();
+
+ ConfigWriter::edit('campaign-monitor')
+ ->remove('add_new_users')
+ ->remove('users')
+ ->save();
+ }
}
diff --git a/src/Subscriber.php b/src/Subscriber.php
index 9eb5780..e5e29e2 100644
--- a/src/Subscriber.php
+++ b/src/Subscriber.php
@@ -15,15 +15,25 @@ class Subscriber
private Collection $config;
- public static function fromSubmission(Submission $submission): self
+ public static function fromSubmission(Submission $submission): ?self
{
- return new self(
- $submission->data(),
- Arr::first(
- config('campaign-monitor.forms', []),
- fn (array $formConfig) => $formConfig['form'] == $submission->form()->handle()
- )
- );
+ if (! $form = $submission->form()) {
+ return null;
+ }
+
+ if (! $config = $form->get('campaign_monitor', [])) {
+ return null;
+ }
+
+ if (! $config['enabled'] ?? false) {
+ return null;
+ }
+
+ if (! $config = Arr::get($config, 'settings', [])) {
+ return null;
+ }
+
+ return new self($submission->data(), $config);
}
public static function fromUser(User $user): self
@@ -37,13 +47,18 @@ public static function fromUser(User $user): self
/**
* @param array|Collection $data
*/
- public function __construct($data, array $config = null)
+ public function __construct($data, ?array $config = null)
{
$this->data = collect($data);
$this->config = collect($config);
}
- private function email(): string
+ public function config(): array
+ {
+ return $this->config->all();
+ }
+
+ public function email(): string
{
return $this->get($this->config->get('primary_email_field', 'email')) ?? '';
}
@@ -127,6 +142,7 @@ public function subscribe(): void
'Value' => $data,
];
}
+
return $r;
}
@@ -134,12 +150,12 @@ public function subscribe(): void
[
'Key' => $item['key'],
'Value' => $fieldData,
- ]
+ ],
];
})
- ->filter()
- ->values()
- ->all(),
+ ->filter()
+ ->values()
+ ->all(),
];
$result = CampaignMonitor::subscribers($this->config->get('list_id'))->add($payload);
@@ -149,4 +165,4 @@ public function subscribe(): void
Log::error(json_encode($result));
}
}
-}
\ No newline at end of file
+}
diff --git a/src/UserConfig.php b/src/UserConfig.php
new file mode 100644
index 0000000..002b6b8
--- /dev/null
+++ b/src/UserConfig.php
@@ -0,0 +1,87 @@
+all();
+ }
+
+ $this->config = $config ?? $this->getSavedSettings();
+ }
+
+ /**
+ * Load user config collection.
+ *
+ * @param array|Collection|null $config
+ * @return static
+ */
+ public static function load($config = null)
+ {
+ $class = app(UserConfig::class);
+
+ return new $class($config);
+ }
+
+ /**
+ * Save user config to yaml.
+ */
+ public function config()
+ {
+ return $this->config;
+ }
+
+ /**
+ * Does it exist yet?
+ */
+ public function exists()
+ {
+ return File::exists($this->path());
+ }
+
+ /**
+ * Save user config to yaml.
+ */
+ public function save()
+ {
+ File::put($this->path(), YAML::dump($this->config));
+ }
+
+ /**
+ * Get user config from yaml
+ *
+ * @return array
+ */
+ protected function getSavedSettings()
+ {
+ return Blink::once('statamic-campaign-monitor::user-config', function () {
+ return collect(YAML::file($this->path())->parse())
+ ->all() ?? [];
+ });
+ }
+
+ /**
+ * Get site defaults yaml path.
+ *
+ * @return string
+ */
+ protected function path()
+ {
+ return resource_path('campaign_monitor.yaml');
+ }
+}
diff --git a/tests/TestCase.php b/tests/TestCase.php
index 951b7e2..f2d3882 100644
--- a/tests/TestCase.php
+++ b/tests/TestCase.php
@@ -2,16 +2,21 @@
namespace StatamicRadPack\CampaignMonitor\Tests;
-use Statamic\Extend\AddonTestCase;
use Statamic\Facades\Blueprint as BlueprintFacade;
use Statamic\Facades\YAML;
use Statamic\Statamic;
+use Statamic\Testing\AddonTestCase;
use StatamicRadPack\CampaignMonitor\ServiceProvider;
class TestCase extends AddonTestCase
{
protected string $addonServiceProvider = ServiceProvider::class;
+ protected function getPackageProviders($app)
+ {
+ return array_merge(parent::getPackageProviders($app), [\Stillat\Proteus\WriterServiceProvider::class]);
+ }
+
protected function resolveApplicationConfiguration($app)
{
parent::resolveApplicationConfiguration($app);
diff --git a/tests/Unit/ListenersTest.php b/tests/Unit/ListenersTest.php
index 60cfa18..334c484 100644
--- a/tests/Unit/ListenersTest.php
+++ b/tests/Unit/ListenersTest.php
@@ -3,6 +3,7 @@
namespace StatamicRadPack\CampaignMonitor\Tests\Unit;
use Illuminate\Support\Facades\Event;
+use PHPUnit\Framework\Attributes\Test;
use Statamic\Events\SubmissionCreated;
use Statamic\Events\UserRegistered;
use Statamic\Facades\Form as FormAPI;
@@ -35,7 +36,7 @@ public function setUp(): void
->data(['foo' => 'bar']);
}
- /** @test */
+ #[Test]
public function does_respond_to_submission_created_event()
{
$event = new SubmissionCreated($this->submission);
@@ -45,7 +46,7 @@ public function does_respond_to_submission_created_event()
Event::dispatch($event);
}
- /** @test */
+ #[Test]
public function does_respond_to_user_registered_event()
{
$event = new UserRegistered([]);
diff --git a/tests/Unit/MigratorTest.php b/tests/Unit/MigratorTest.php
new file mode 100644
index 0000000..5882146
--- /dev/null
+++ b/tests/Unit/MigratorTest.php
@@ -0,0 +1,37 @@
+handle('test')
+ ->data([])
+ ->save();
+
+ (new ConfigToFormData)
+ ->handle([
+ 'form' => 'test',
+ 'check_consent' => true,
+ ]);
+
+ $data = Form::find('test')->data()->all();
+
+ $this->assertArrayHasKey('campaign_monitor', $data);
+
+ $this->assertSame($data['campaign_monitor'], [
+ 'enabled' => true,
+ 'settings' => [
+ 'check_consent' => true,
+ ],
+ ]);
+ }
+}
diff --git a/tests/Unit/SubscriberFromSubmissionTest.php b/tests/Unit/SubscriberFromSubmissionTest.php
index ef1c1a9..d14fdf4 100644
--- a/tests/Unit/SubscriberFromSubmissionTest.php
+++ b/tests/Unit/SubscriberFromSubmissionTest.php
@@ -2,6 +2,7 @@
namespace StatamicRadPack\CampaignMonitor\Tests\Unit;
+use PHPUnit\Framework\Attributes\Test;
use Statamic\Facades\Form as FormAPI;
use Statamic\Forms\Form;
use Statamic\Forms\Submission;
@@ -33,7 +34,7 @@ public function setUp(): void
]);
}
- /** @test */
+ #[Test]
public function can_create_subscriber_from_submission()
{
$formConfig = [[
@@ -46,7 +47,7 @@ public function can_create_subscriber_from_submission()
$this->assertInstanceOf(Subscriber::class, $subscriber);
}
- /** @test */
+ #[Test]
public function has_consent_by_default()
{
$formConfig = [
@@ -60,7 +61,7 @@ public function has_consent_by_default()
$this->assertTrue($consent);
}
- /** @test */
+ #[Test]
public function no_consent_when_no_consent_field()
{
$formConfig = [
@@ -77,7 +78,7 @@ public function no_consent_when_no_consent_field()
$this->assertFalse($consent);
}
- /** @test */
+ #[Test]
public function no_consent_when_consent_field_is_false()
{
$formConfig = [
@@ -96,7 +97,7 @@ public function no_consent_when_consent_field_is_false()
$this->assertFalse($consent);
}
- /** @test */
+ #[Test]
public function consent_when_default_consent_field_is_true()
{
$formConfig = [
@@ -115,7 +116,7 @@ public function consent_when_default_consent_field_is_true()
$this->assertTrue($consent);
}
- /** @test */
+ #[Test]
public function consent_when_configured_consent_field_is_true()
{
$formConfig =
@@ -135,4 +136,25 @@ public function consent_when_configured_consent_field_is_true()
$this->assertTrue($consent);
}
+
+ #[Test]
+ public function it_gets_config_from_form()
+ {
+ $settings = [
+ 'check_consent' => true,
+ 'primary_email_field' => 'email',
+ ];
+
+ $this->form->merge([
+ 'campaign_monitor' => [
+ 'enabled' => true,
+ 'settings' => $settings,
+ ],
+ ])->save();
+
+ $subscriber = Subscriber::fromSubmission($this->submission);
+
+ $this->assertSame($settings, $subscriber->config());
+ $this->assertSame($subscriber->email(), 'foo@bar.com');
+ }
}
diff --git a/tests/Unit/SubscriberFromUserTest.php b/tests/Unit/SubscriberFromUserTest.php
index 0f1c60b..b4c2ea3 100644
--- a/tests/Unit/SubscriberFromUserTest.php
+++ b/tests/Unit/SubscriberFromUserTest.php
@@ -2,6 +2,7 @@
namespace StatamicRadPack\CampaignMonitor\Tests\Unit;
+use PHPUnit\Framework\Attributes\Test;
use Statamic\Facades\User;
use StatamicRadPack\CampaignMonitor\Subscriber;
use StatamicRadPack\CampaignMonitor\Tests\TestCase;
@@ -19,7 +20,7 @@ public function setUp(): void
->password('password');
}
- /** @test */
+ #[Test]
public function can_create_subscriber_from_user()
{
$config = [[
@@ -31,7 +32,7 @@ public function can_create_subscriber_from_user()
$this->assertInstanceOf(Subscriber::class, $subscriber);
}
- /** @test */
+ #[Test]
public function has_consent_by_default()
{
$subscriber = new Subscriber($this->userData(), []);
@@ -39,7 +40,7 @@ public function has_consent_by_default()
$this->assertTrue($subscriber->hasConsent());
}
- /** @test */
+ #[Test]
public function no_consent_when_no_consent_field()
{
$config = [
@@ -51,7 +52,7 @@ public function no_consent_when_no_consent_field()
$this->assertFalse($subscriber->hasConsent());
}
- // /** @test */
+ // #[Test]
// public function no_consent_when_consent_field_is_false()
// {
// $formConfig = [
@@ -70,7 +71,7 @@ public function no_consent_when_no_consent_field()
// $this->assertFalse($consent);
// }
- // /** @test */
+ // #[Test]
// public function consent_when_default_consent_field_is_true()
// {
// $formConfig = [
@@ -89,7 +90,7 @@ public function no_consent_when_no_consent_field()
// $this->assertTrue($consent);
// }
- // /** @test */
+ // #[Test]
// public function consent_when_configured_consent_field_is_true()
// {
// $formConfig =