Skip to content

Commit 4c4bf9e

Browse files
author
markus-moser
authored
Handle lists in multiple Mailchimp accounts (#172)
* Add the possibility to handle lists in multiple mailchimp accounts. * fix missing namespace in import * Fix several bugs related to multiple mailchimp accounts
1 parent 37b7906 commit 4c4bf9e

File tree

12 files changed

+277
-108
lines changed

12 files changed

+277
-108
lines changed
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# Multiple Mailchimp Accounts
2+
3+
Optionally it's possible to configure the service container to be able to handle multiple mailchimp accounts. Principally it's handled the same way like newsletter lists via mailchimp provider handler services (see [Configuration](../03_Configuration.md) for an example definition)*[]:
4+
5+
But additionally to the standard constructor arguments of the mailchimp provider handler class it's needed to setup a specialized export service which holds the Mailchimp client with the alternative API key.
6+
7+
An example config might look like this:
8+
9+
```yaml
10+
appbundle.cmf.mailchimp.client:
11+
class: DrewM\MailChimp
12+
arguments:
13+
- 'my-example-api-key'
14+
15+
appbundle.cmf.mailchimp.export-service:
16+
class: CustomerManagementFrameworkBundle\Newsletter\ProviderHandler\Mailchimp\MailChimpExportService
17+
arguments:
18+
- '@appbundle.cmf.mailchimp.client'
19+
20+
appbundle.cmf.mailchimp.handler.list1:
21+
class: CustomerManagementFrameworkBundle\Newsletter\ProviderHandler\Mailchimp
22+
autowire: true
23+
arguments:
24+
# Shortcut of the handler/list for internal use
25+
$shortcut: list1
26+
27+
# List ID within Mailchimp
28+
$listId: ls938393f
29+
30+
# Mapping of Pimcore status field => Mailchimp status
31+
$statusMapping:
32+
manuallySubscribed: subscribed
33+
singleOptIn: subscribed
34+
doubleOptIn: subscribed
35+
unsubscribed: unsubscribed
36+
pending: pending
37+
38+
# Reverse mapping of Mailchimp status => Pimcore status field
39+
$reverseStatusMapping:
40+
subscribed: doubleOptIn
41+
unsubscribed: unsubscribed
42+
pending: pending
43+
44+
# Mapping of Pimcore data object attributes => Mailchimp merge fields
45+
$mergeFieldMapping:
46+
firstname: FNAME
47+
lastname: LNAME
48+
street: STREET
49+
birthDate: BIRTHDATE
50+
51+
# Special data transfromer for the birthDate field.
52+
# This ensures that the correct data format will be used.
53+
$fieldTransformers:
54+
birthDate: '@appbundle.cmf.mailchimp.birthdate-transformer'
55+
56+
$exportService: '@appbundle.cmf.mailchimp.export-service'
57+
58+
tags: [cmf.newsletter_provider_handler]
59+
60+
```

doc/24_NewsletterSync/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ Further than that, the CMF can handle multiple MailChimp lists. Each list is one
1717
See [Configuration](../03_Configuration.md) for an example configuration of such a service and for a list of general
1818
newsletter related settings.
1919

20+
See [Multiple Mailchimp Accounts](./MultipleMailchimpAccounts.md) if you need to handle lists within different Mailchimp accounts.
21+
2022

2123
## Prepare Data Objects for MailChimp Sync
2224

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
<?php
2+
3+
/**
4+
* Pimcore
5+
*
6+
* This source file is available under two different licenses:
7+
* - GNU General Public License version 3 (GPLv3)
8+
* - Pimcore Enterprise License (PEL)
9+
* Full copyright and license information is available in
10+
* LICENSE.md which is distributed with this source code.
11+
*
12+
* @copyright Copyright (c) Pimcore GmbH (http://www.pimcore.org)
13+
* @license http://www.pimcore.org/license GPLv3 and PEL
14+
*/
15+
16+
namespace CustomerManagementFrameworkBundle\Event\Newsletter\Mailchimp;
17+
18+
use CustomerManagementFrameworkBundle\Newsletter\ProviderHandler\Mailchimp;
19+
use Symfony\Component\EventDispatcher\Event;
20+
use Pimcore\Model\Document;
21+
22+
class TemplateExportResolveProviderHandlerEvent extends Event
23+
{
24+
const NAME = 'plugin.cmf.newsletter.mailchimp.template-export-resolve-provider-handler';
25+
26+
/**
27+
* @var Mailchimp|null
28+
*/
29+
private $providerHandler;
30+
31+
/**
32+
* @var Document\PageSnippet $document
33+
*/
34+
private $document;
35+
36+
/**
37+
* @param Document\PageSnippet $document
38+
*/
39+
public function __construct(Document\PageSnippet $document)
40+
{
41+
$this->document = $document;
42+
}
43+
44+
public function getName()
45+
{
46+
return self::NAME;
47+
}
48+
49+
/**
50+
* @return Mailchimp|null
51+
*/
52+
public function getProviderHandler(): Mailchimp
53+
{
54+
return $this->providerHandler;
55+
}
56+
57+
/**
58+
* @return Document\PageSnippet
59+
*/
60+
public function getDocument(): Document\PageSnippet
61+
{
62+
return $this->document;
63+
}
64+
65+
/**
66+
* @param Mailchimp|null $providerHandler
67+
*/
68+
public function setProviderHandler(Mailchimp $providerHandler)
69+
{
70+
$this->providerHandler = $providerHandler;
71+
}
72+
}

src/Newsletter/ProviderHandler/Mailchimp.php

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -438,7 +438,7 @@ public function updateSegmentGroups($forceUpdate = false)
438438

439439
$groupIds = [];
440440
foreach ($groups as $group) {
441-
$remoteGroupId = $this->segmentExporter->exportGroup($group, $this->listId, false, $forceUpdate);
441+
$remoteGroupId = $this->segmentExporter->exportGroup($group, $this, false, $forceUpdate);
442442

443443
$groupIds[] = $remoteGroupId;
444444

@@ -454,13 +454,13 @@ public function updateSegmentGroups($forceUpdate = false)
454454
/**
455455
* @var CustomerSegment $segment
456456
*/
457-
$segmentIds[] = $this->segmentExporter->exportSegment($segment, $this->listId, $remoteGroupId, $forceCreate, $forceUpdate);
457+
$segmentIds[] = $this->segmentExporter->exportSegment($segment, $this, $remoteGroupId, $forceCreate, $forceUpdate);
458458
}
459459

460-
$this->segmentExporter->deleteNonExistingSegmentsFromGroup($segmentIds, $this->listId, $remoteGroupId);
460+
$this->segmentExporter->deleteNonExistingSegmentsFromGroup($segmentIds, $this, $remoteGroupId);
461461
}
462462

463-
$this->segmentExporter->deleteNonExistingGroups($groupIds, $this->listId);
463+
$this->segmentExporter->deleteNonExistingGroups($groupIds, $this);
464464
}
465465

466466
protected function getExportableSegmentGroups()
@@ -856,6 +856,14 @@ public function getActiveCustomerByEmail($email)
856856
return $customer;
857857
}
858858

859+
/**
860+
* @return MailChimpExportService
861+
*/
862+
public function getExportService(): MailChimpExportService
863+
{
864+
return $this->exportService;
865+
}
866+
859867
protected function getCustomerProvider(): CustomerProviderInterface
860868
{
861869
/**

src/Newsletter/ProviderHandler/Mailchimp/CliSyncProcessor.php

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,6 @@ class CliSyncProcessor
3333
*/
3434
protected $pimcoreUserName;
3535

36-
/**
37-
* @var MailChimpExportService
38-
*/
39-
protected $exportService;
40-
4136
/**
4237
* @var CustomerProviderInterface
4338
*/
@@ -53,7 +48,7 @@ class CliSyncProcessor
5348
*/
5449
protected $newsletterManager;
5550

56-
public function __construct($pimcoreUserName = null, MailChimpExportService $exportService, CustomerProviderInterface $customerProvider, UpdateFromMailchimpProcessor $updateFromMailchimpProcessor, NewsletterManagerInterface $newsletterManager)
51+
public function __construct($pimcoreUserName = null, CustomerProviderInterface $customerProvider, UpdateFromMailchimpProcessor $updateFromMailchimpProcessor, NewsletterManagerInterface $newsletterManager)
5752
{
5853
$this->setLoggerComponent('NewsletterSync');
5954

@@ -65,19 +60,19 @@ public function __construct($pimcoreUserName = null, MailChimpExportService $exp
6560
}
6661
}
6762

68-
$this->exportService = $exportService;
6963
$this->customerProvider = $customerProvider;
7064
$this->updateFromMailchimpProcessor = $updateFromMailchimpProcessor;
7165
$this->newsletterManager = $newsletterManager;
7266
}
7367

7468
public function syncStatusChanges()
7569
{
76-
$client = $this->exportService->getApiClient();
77-
7870
foreach ($this->newsletterManager->getNewsletterProviderHandlers() as $newsletterProviderHandler) {
7971
if ($newsletterProviderHandler instanceof Mailchimp) {
8072

73+
$exportService = $newsletterProviderHandler->getExportService();
74+
$client = $exportService->getApiClient();
75+
8176
// get updates from the last 30 days
8277
$date = Carbon::createFromTimestamp(time() - (60 * 60 * 24 * 30));
8378
$date = $date->toIso8601String();
@@ -86,7 +81,7 @@ public function syncStatusChanges()
8681
$page = 0;
8782
while(true) {
8883
$result = $client->get(
89-
$this->exportService->getListResourceUrl(
84+
$exportService->getListResourceUrl(
9085
$newsletterProviderHandler->getListId(),
9186
'members/?since_last_changed='.urlencode($date) . '&count=' . $count . '&offset=' . ($page * $count)
9287
)
@@ -161,15 +156,17 @@ public function syncStatusChanges()
161156

162157
public function deleteNonExistingItems()
163158
{
164-
$client = $this->exportService->getApiClient();
165159

166160
foreach ($this->newsletterManager->getNewsletterProviderHandlers() as $newsletterProviderHandler) {
167161
if ($newsletterProviderHandler instanceof Mailchimp) {
168162

163+
$exportService = $newsletterProviderHandler->getExportService();
164+
$client = $exportService->getApiClient();
165+
169166
$count = 20;
170167
$page = 0;
171168
while(true) {
172-
$url = $this->exportService->getListResourceUrl($newsletterProviderHandler->getListId(), 'members/?count=' . $count . '&offset=' . ($page * $count) );
169+
$url = $exportService->getListResourceUrl($newsletterProviderHandler->getListId(), 'members/?count=' . $count . '&offset=' . ($page * $count) );
173170
$result = $client->get(
174171
$url
175172
);
@@ -201,7 +198,7 @@ public function deleteNonExistingItems()
201198
);
202199

203200
$client->delete(
204-
$this->exportService->getListResourceUrl($newsletterProviderHandler->getListId(), sprintf('members/%s', $remoteId))
201+
$exportService->getListResourceUrl($newsletterProviderHandler->getListId(), sprintf('members/%s', $remoteId))
205202
);
206203

207204
if ($client->success()) {

src/Newsletter/ProviderHandler/Mailchimp/CustomerExporter/AbstractExporter.php

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ abstract class AbstractExporter
3232
protected $exportService;
3333

3434
/**
35-
* @var MailChimp
35+
* @var MailChimp|null
3636
*/
3737
protected $apiClient;
3838

@@ -42,26 +42,22 @@ abstract class AbstractExporter
4242
protected $newsletterQueue;
4343

4444
/**
45-
* AbstractExporter constructor.
46-
*
47-
* @param MailChimpExportService $interpreter
45+
* @param NewsletterQueueInterface $newsletterQueue
4846
*/
49-
public function __construct(MailChimpExportService $exportService, NewsletterQueueInterface $newsletterQueue)
47+
public function __construct(NewsletterQueueInterface $newsletterQueue)
5048
{
51-
$this->exportService = $exportService;
52-
$this->apiClient = $exportService->getApiClient();
5349
$this->newsletterQueue = $newsletterQueue;
5450
$this->setLoggerComponent('NewsletterSync');
5551
}
56-
52+
5753
/**
5854
* Get an array containing the HTTP headers and the body of the API response.
5955
*
6056
* @return array Assoc array with keys 'headers' and 'body'
6157
*/
6258
public function getLastResponse()
6359
{
64-
return $this->apiClient->getLastResponse();
60+
return $this->apiClient ? $this->apiClient->getLastResponse() : [];
6561
}
6662

6763
/**
@@ -75,4 +71,16 @@ protected function getCustomer($id)
7571
->get('cmf.customer_provider')
7672
->getById($id);
7773
}
74+
75+
/**
76+
* used to be able to track the last response independently of the concrete mailchimp account
77+
*
78+
* @param MailChimpExportService $exportService
79+
* @return MailChimp
80+
*/
81+
protected function getApiClientFromExportService(MailChimpExportService $exportService): MailChimp
82+
{
83+
$this->apiClient = $exportService->getApiClient();
84+
return $exportService->getApiClient();
85+
}
7886
}

0 commit comments

Comments
 (0)