Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Push additional contact data #343

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions CRM/Mailchimp/Api3.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ class CRM_Mailchimp_Api3 {
* Nb. a CiviCRM_Core_Error::debug_log_message facility is injected if you
* enable debugging on the Mailchimp settings screen. But you can inject
* something different, e.g. for testing.
*/
*/
protected $log_facility;
/**
* @param array $settings contains key 'api_key', possibly other settings.
Expand All @@ -69,10 +69,10 @@ public function __construct($settings) {
}
$this->api_key = $settings['api_key'];

// Set URL based on datacentre identifier at end of api key.
// Set URL based on datacentre identifier at end of api key.
preg_match('/^.*-([^-]+)$/', $this->api_key, $matches);
if (empty($matches[1])) {
throw new InvalidArgumentException("Invalid API key - could not extract datacentre from given API key.");
throw new InvalidArgumentException("Invalid API key - could not extract datacentre from given API key.");
}

if (!empty($settings['log_facility'])) {
Expand All @@ -87,7 +87,7 @@ public function __construct($settings) {
*/
public function setLogFacility($callback) {
if (!is_callable($callback)) {
throw new InvalidArgumentException("Log facility callback is not callable.");
throw new InvalidArgumentException("Log facility callback is not callable.");
}
$this->log_facility = $callback;
}
Expand Down Expand Up @@ -234,7 +234,7 @@ public function setNetworkEnabled($enable=TRUE) {
/**
* Provide mock for curl.
*
* The callback will be called with the
* The callback will be called with the
* request object in $this->request. It must return an array with optional
* keys:
*
Expand Down Expand Up @@ -299,7 +299,7 @@ protected function makeRequest($method, $url, $data=null) {
if ($this->request->method == 'GET') {
// For GET requests, data must be added as query string.
// Append if there's already a query string.
$query_string = http_build_query($data);
$query_string = http_build_query($data, '', '&');
if ($query_string) {
$this->request->url .= ((strpos($this->request->url, '?')===false) ? '?' : '&')
. $query_string;
Expand Down
132 changes: 125 additions & 7 deletions CRM/Mailchimp/Form/Setting.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,9 @@ public function buildQuickForm() {
// Add the API Key Element
$this->add('text', 'mailchimp_api_key', ts('API Key'), array(
'size' => 48,
), TRUE);
), TRUE);

// Add the User Security Key Element
// Add the User Security Key Element
$this->add('text', 'mailchimp_security_key', ts('Security Key'), array(
'size' => 24,
), TRUE);
Expand All @@ -53,6 +53,25 @@ public function buildQuickForm() {
$enableOptions = array(1 => ts('Yes'), 0 => ts('No'));
$this->addRadio('mailchimp_enable_debugging', ts('Enable Debugging'), $enableOptions, NULL);


$result = civicrm_api3('UFGroup', 'get', array(
'sequential' => 1,
'group_type' => "Contact",
'is_active' => 1,
));
// Add profile selection for syncronization.
$profileOptions = array(0 => '-- None --');
if (!empty($result['values'])) {
foreach ($result['values'] as $profile) {
$profileOptions[$profile['id']] = $profile['title'];
}
}
$yesNo = array(1 => ts('Yes'), 0 => ts('No'));
$this->addRadio('mailchimp_sync_checksum', ts('Sync Checksum and Contact ID'), $yesNo, NULL);
$this->add('select', 'mailchimp_sync_profile', ts('Sync fields from profile'), $profileOptions);
// Not a setting.
$this->addRadio('mailchimp_create_merge_fields', ts('Create missing fields on mailchimp lists'), $yesNo, NULL);
$this->addRadio('mailchimp_sync_tags', ts('Sync Tags?'), $yesNo, NULL);
// Create the Submit Button.
$buttons = array(
array(
Expand All @@ -62,7 +81,7 @@ public function buildQuickForm() {
array(
'type' => 'cancel',
'name' => ts('Cancel'),
),
),
);

// Add the Buttons.
Expand Down Expand Up @@ -94,9 +113,16 @@ public function setDefaultValues() {
}

$enableDebugging = Civi::settings()->get('mailchimp_enable_debugging');
$syncProfile = Civi::settings()->get('mailchimp_sync_profile');
$syncChecksum = Civi::settings()->get('mailchimp_sync_checksum');
$syncTags = Civi::settings()->get('mailchimp_sync_tags');

$defaults['mailchimp_api_key'] = $apiKey;
$defaults['mailchimp_security_key'] = $securityKey;
$defaults['mailchimp_enable_debugging'] = $enableDebugging;
$defaults['mailchimp_sync_profile'] = $syncProfile;
$defaults['mailchimp_sync_checksum'] = $syncChecksum;
$defaults['mailchimp_sync_tags'] = $syncTags;

return $defaults;
}
Expand All @@ -116,7 +142,14 @@ public function postProcess() {
if (CRM_Utils_Array::value('mailchimp_api_key', $params) || CRM_Utils_Array::value('mailchimp_security_key', $params)) {


foreach (['mailchimp_api_key', 'mailchimp_enable_debugging', 'mailchimp_security_key'] as $_) {
foreach ([
'mailchimp_api_key',
'mailchimp_enable_debugging',
'mailchimp_security_key',
'mailchimp_sync_checksum',
'mailchimp_sync_tags',
'mailchimp_sync_profile',
] as $_) {
Civi::settings()->set($_, $params[$_]);
}

Expand All @@ -143,7 +176,11 @@ public function postProcess() {
// Check CMS's permission for (presumably) anonymous users.
if (!self::checkMailchimpPermission($params['mailchimp_security_key'])) {
CRM_Core_Session::setStatus(ts("Mailchimp WebHook URL requires 'allow webhook posts' permission to be set for any user roles."));
}
}
// Create Merge Fields from for each list.
if (!empty($params['mailchimp_sync_profile']) && !empty($params['mailchimp_create_merge_fields'])) {
$this->createMailchimpMergeFields($params['mailchimp_sync_profile']);
}
}
}

Expand All @@ -157,7 +194,7 @@ public static function checkMailchimpPermission($securityKey) {
'key' => $securityKey,
);
$webhook_url = CRM_Utils_System::url('civicrm/mailchimp/webhook', $urlParams, TRUE, NULL, FALSE, TRUE);

$curl = curl_init();

curl_setopt_array($curl, array(
Expand All @@ -180,7 +217,88 @@ public static function checkMailchimpPermission($securityKey) {
curl_close($curl);

return ($info['http_code'] != 200) ? FALSE : TRUE;
}
}

public function createMailchimpMergeFields($profileID, $includeChecksum=FALSE) {
// Get custom fields from profile and create data for creating on MC.
$ufFieldResult = civicrm_api3('UFField', 'get', ['uf_group_id' => $profileID]);
$mergeFields = $existingFields = array();
if (!empty($ufFieldResult['values'])) {
foreach ($ufFieldResult['values'] as $field) {
if (0 === strpos($field['field_name'],'custom_') && $field['is_active']) {
$mergeFields[$field['field_name']] = [
'tag' => strtoupper($field['field_name']),
'name' => $field['label'],
// By default make all fields type text and not public.
'type' => 'text',
'public' => FALSE,
];
}
}
}
// Checksum and contact id.
if (Civi::settings()->get('mailchimp_sync_checksum')) {
$default = ['type' => 'text', 'public' => FALSE];
foreach ([
'contact_id' => 'Contact ID',
'checksum' => 'Checksum'

] as $tag => $name) {
$mergeFields[$tag] = array_merge(['tag' => strtoupper($tag), 'name' => $name], $default);
}
}

// Get existing fields for each list.
$listResult = civicrm_api3('Mailchimp', 'getlists');
$msg = [];
if (!empty($listResult['values'])) {
foreach ($listResult['values'] as $listId => $listName) {
$listCreateFields = $mergeFields;
$existingFields = $this->getMergeFields($listId);
foreach($existingFields as $mergeField) {
$key = strtolower($mergeField->tag);
if (isset($listCreateFields[$key])) {
CRM_Core_Session::setStatus("Field $key exists on $listName, skipping");
unset($listCreateFields[$key]);
}
}
// Create the merge field for the list.
foreach ($listCreateFields as $createField) {
$response = $this->createMergeField($listId, $createField);
if ($response && $response->http_code == 200) {
$name = $response->data->name;
$tag = $response->data->tag;
CRM_Core_Session::setStatus( "$name ($tag) created for $listName.", "Created field On Mailchimp");
}
}
}
}
}

/**
* Get Merge Field definitions for a Mailchimp Group.
* @param string $listId
* @return array
*/
protected function getMergeFields($listId) {
$mcClient = CRM_Mailchimp_Utils::getMailchimpApi(TRUE);
$path = '/lists/' . $listId . '/merge-fields';
$response = $mcClient->get($path);
return $response->data->merge_fields;
}

protected function createMergeField($listId, $data) {
$mcClient = CRM_Mailchimp_Utils::getMailchimpApi(TRUE);
$path = '/lists/' . $listId . '/merge-fields';
try {
$response = $mcClient->post($path, $data);
}
catch (Exception $e) {
CRM_Core_Error::debug_log_message($e->getMessage());
CRM_Core_Error::debug_var(__CLASS__ . __FUNCTION__, $response);
}
return $response;
}
}


2 changes: 1 addition & 1 deletion CRM/Mailchimp/Form/Sync.php
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,7 @@ public static function syncPushToMailchimp(CRM_Queue_TaskContext $ctx, $listID,
// Finally, finish up by removing the two temporary tables
//CRM_Mailchimp_Sync::dropTemporaryTables();
static::updatePushStats($stats);

CRM_Mailchimp_Utils::checkDebug('End-CRM_Mailchimp_Form_Sync syncPushAdd $listID= ', $listID);
return CRM_Queue_Task::TASK_SUCCESS;
}

Expand Down
Loading