mailchimp.module in Mailchimp 7.2
Mailchimp module.
File
mailchimp.moduleView source
<?php
/**
* @file
* Mailchimp module.
*/
/**
* Implements hook_libraries_info().
*/
function mailchimp_libraries_info() {
$libraries['mailchimp'] = array(
'name' => 'MailChimp MCAPI',
'vendor url' => 'http://apidocs.mailchimp.com/api/1.3',
'download url' => 'http://apidocs.mailchimp.com/api/downloads/mailchimp-api-class.zip',
'version arguments' => array(
'file' => 'MCAPI.class.php',
// Version 1.3
'pattern' => '/\\$version = \\"((\\d+)\\.(\\d+))\\"/',
),
'files' => array(
'php' => array(
'MCAPI.class.php',
),
),
);
return $libraries;
}
/**
* Implements hook_menu().
*/
function mailchimp_menu() {
$items = array();
$items['admin/config/services/mailchimp'] = array(
'title' => 'MailChimp',
'description' => 'Manage MailChimp Settings.',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'mailchimp_admin_settings',
),
'access arguments' => array(
'administer mailchimp',
),
'file' => 'includes/mailchimp.admin.inc',
'type' => MENU_NORMAL_ITEM,
);
$items['admin/config/services/mailchimp/global'] = array(
'title' => 'Global Settings',
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => 10,
);
$items['mailchimp/webhook'] = array(
'title' => 'MailChimp webhooks endpoint',
'page callback' => 'mailchimp_process_webhook',
'access callback' => 'mailchimp_process_webhook_access',
'access arguments' => array(
2,
),
'type' => MENU_CALLBACK,
);
return $items;
}
/**
* Implements hook_permission().
*/
function mailchimp_permission() {
return array(
'administer mailchimp' => array(
'title' => t('administer mailchimp'),
'description' => t('TODO Add a description for administer mailchimp'),
),
);
}
/**
* Check if the given email is subscribed to the given list.
*
* Simple wrapper around mailchimp_get_memberinfo().
*
* @param string $list_id
* Unique string identifier for the list on your MailChimp account.
* @param string $email
* Email address to check for on the identified Mailchimp List
* @param bool $reset
* Set to TRUE to ignore the cache. (Used heavily in testing functions.)
*
* @return bool
* Indicates subscription status.
*/
function mailchimp_is_subscribed($list_id, $email, $reset = FALSE) {
$subscribed = FALSE;
$memberinfo = mailchimp_get_memberinfo($list_id, $email, $reset);
if (isset($memberinfo['status']) && $memberinfo['status'] == 'subscribed') {
$subscribed = TRUE;
}
return $subscribed;
}
/**
* Subscribe a user to a given list.
*/
function mailchimp_subscribe_user($list, $email, $merge_vars, $message = TRUE, $mcapi = NULL) {
$success = FALSE;
if ($mcapi || ($mcapi = mailchimp_get_api_object())) {
$double_optin = $list->settings['doublein'];
$success = $mcapi
->listSubscribe($list->mc_list_id, $email, $merge_vars, 'html', $double_optin, TRUE);
if ($message && $success && $double_optin) {
drupal_set_message(t('You have chosen to subscribe to %list. An email will be sent to your address. Click the link in the email to confirm the subscription.', array(
'%list' => $list->label,
)));
}
elseif ($message && $success) {
drupal_set_message(t('You have subscribed to %list.', array(
'%list' => $list->label,
)));
}
// Clear user cache, just in case there's some cruft leftover:
mailchimp_cache_clear_user($list->mc_list_id, $email);
if ($success) {
module_invoke_all('mailchimp_subscribe_user', $list, $email, $merge_vars);
watchdog('mailchimp', '@email was subscribed to list @list.', array(
'@email' => $merge_vars['EMAIL'],
'@list' => $list->label,
), WATCHDOG_NOTICE);
}
else {
watchdog('mailchimp', 'A problem occurred subscribing @email to list @list. Message: @msg', array(
'@email' => $merge_vars['EMAIL'],
'@list' => $list->label,
'@msg' => $mcapi->errorMessage,
), WATCHDOG_WARNING);
}
}
return $success;
}
/**
* Update a user in a given list.
*/
function mailchimp_update_user($list, $email, $merge_vars, $message = TRUE, $mcapi = NULL) {
$success = FALSE;
if ($mcapi || ($mcapi = mailchimp_get_api_object())) {
$success = $mcapi
->listUpdateMember($list->mc_list_id, $email, $merge_vars);
if ($success && $message) {
drupal_set_message(t('You have updated your settings in %list.', array(
'%list' => $list->label,
)));
}
// Clear user cache:
mailchimp_cache_clear_user($list->mc_list_id, $email);
if ($success) {
watchdog('mailchimp', '@email was updated in list @list.', array(
'@email' => $merge_vars['EMAIL'],
'@list' => $list->label,
), WATCHDOG_NOTICE);
}
else {
watchdog('mailchimp', 'A problem occurred subscribing @email to list @list. Message: @msg', array(
'@email' => $merge_vars['EMAIL'],
'@list' => $list->label,
'@msg' => $mcapi->errorMessage,
), WATCHDOG_WARNING);
}
}
return $success;
}
/**
* Unsubscribe a user from the given list.
*
* @param stdclass $list
* A mailchimp lists entity.
* @param string $email
* Email address to be unsubscribed.
* @param bool $message
* Whether or not to display a message in the web interface.
* @param object $mcapi
* Mailchimp API object if one is already loaded.
* @param bool $delete
* Indicates whether an email should be deleted or just unsubscribed.
*
* @return bool
* Indicates whether unsubscribe was successful.
*/
function mailchimp_unsubscribe_user($list, $email, $message = TRUE, $mcapi = NULL, $delete = FALSE) {
$success = FALSE;
if ($mcapi || ($mcapi = mailchimp_get_api_object())) {
if (mailchimp_is_subscribed($list->mc_list_id, $email)) {
$success = $mcapi
->listUnsubscribe($list->mc_list_id, $email, $delete, FALSE, FALSE);
if ($success) {
module_invoke_all('mailchimp_unsubscribe_user', $list, $email);
if ($message) {
drupal_set_message(t('You have unsubscribed from %list.', array(
'%list' => $list->label,
)));
}
}
// Clear user cache:
mailchimp_cache_clear_user($list->mc_list_id, $email);
}
}
return $success;
}
/**
* Get a Mailchimp API object for communication with the mailchimp server.
*
* @return MCAPI|NULL
* A valid MCAPI implementation or NULL if no one found.
*/
function mailchimp_get_api_object() {
$library = libraries_load('mailchimp');
if (!$library['installed']) {
$msg = 'Failed to load MailChimp PHP library. Please refer to the installation requirements.';
watchdog('mailchimp', $msg, array(), WATCHDOG_ERROR);
drupal_set_message(t($msg), 'error');
return NULL;
}
$api_key = variable_get('mailchimp_api_key', '');
// We allow the class name to be overridden, following the example of core's
// mailsystem, in order to use alternate MailChimp classes. The bundled tests
// use this approach to extend the MailChimp class with a test server.
$classname = variable_get('mailchimp_api_classname', 'MailChimp');
$q = new $classname($api_key);
// Set the timeout to something that won't take down the Drupal site:
$q
->setTimeout(60);
// Specify if a secure connection should be used with the API:
$q
->useSecure(variable_get('mailchimp_use_secure', TRUE));
if ($q->errorCode) {
watchdog('mailchimp', 'MCAPI Error: %errmsg', array(
'%errmsg' => $q->errorMessage,
), WATCHDOG_ERROR);
return NULL;
}
return $q;
}
/**
* Return all MailChimp lists for a given key. Lists are stored in the cache.
*
* @param array $list_ids
* An array of list IDs to filter the results by.
* @param bool $reset
* Force a cache reset.
*
* @return array
* An array of list arrays.
*/
function mailchimp_get_lists($list_ids = array(), $reset = FALSE) {
$cache = $reset ? NULL : cache_get('mailchimp_lists');
$lists = array();
// Return cached lists:
if ($cache) {
$lists = $cache->data;
}
else {
if ($q = mailchimp_get_api_object()) {
$result = $q
->lists(array(), 0, 100);
if ($result['total'] > 0) {
foreach ($result['data'] as $list) {
// Append mergefields:
$list['mergevars'] = $q
->listMergeVars($list['id']);
// Append interest groups:
$list['intgroups'] = $q
->listInterestGroupings($list['id']);
$lists[$list['id']] = $list;
}
}
}
uasort($lists, '_mailchimp_list_cmp');
cache_set('mailchimp_lists', $lists, 'cache', CACHE_TEMPORARY);
}
// Filter by given ids:
if (!empty($list_ids)) {
foreach ($lists as $key => $list) {
if (!in_array($key, $list_ids)) {
unset($lists[$key]);
}
}
}
return $lists;
}
/**
* Wrapper around mailchimp_get_lists() to return a single list.
*
* @param string $list_id
* The unique ID of the list provided by MailChimp.
*
* @return array
* A list array formatted as indicated in the MailChimp API documentation.
*/
function mailchimp_get_list($list_id) {
$lists = mailchimp_get_lists(array(
$list_id,
));
return reset($lists);
}
/**
* Get the MailChimp memberinfo for a given email address and list.
*
* Results are cached in the cache_mailchimp_user bin which is cleared by the MC
* web hooks system when needed.
*
* @param string $list_id
* @param string $email
* @param bool $reset
*
* @return array
* memberinfo array.
*/
function mailchimp_get_memberinfo($list_id, $email, $reset = FALSE) {
$cache = $reset ? NULL : cache_get($list_id . '-' . $email, 'cache_mailchimp_user');
$memberinfo = array();
// Return cached lists:
if ($cache) {
$memberinfo = $cache->data;
}
else {
if ($q = mailchimp_get_api_object()) {
$result = $q
->listMemberInfo($list_id, array(
$email,
));
if ($result['success']) {
$memberinfo = reset($result['data']);
}
}
cache_set($list_id . '-' . $email, $memberinfo, 'cache_mailchimp_user', CACHE_PERMANENT);
}
return $memberinfo;
}
/**
* Sets the member info in the cache.
*
* @param string $list_id
* @param string $email
*/
function mailchimp_set_memberinfo($list_id, $email) {
mailchimp_get_memberinfo($list_id, $email, TRUE);
}
/**
* Clear a mailchimp user memberinfo cache.
*
* @param string $list_id
* @param $email
*/
function mailchimp_cache_clear_user($list_id, $email) {
cache_clear_all($list_id . '-' . $email, 'cache_mailchimp_user');
}
/**
* Clear a mailchimp activity cache.
*/
function mailchimp_cache_clear_list_activity($list_id) {
cache_clear_all('mailchimp_activity_' . $list_id, 'cache');
}
/**
* Clear a mailchimp activity cache.
*/
function mailchimp_cache_clear_campaign($campaign_id) {
cache_clear_all('mailchimp_campaign_' . $campaign_id, 'cache');
}
/**
* Implements hook_flush_caches().
*/
function mailchimp_flush_caches() {
return array(
'cache_mailchimp_user',
);
}
/**
* Access callback for mailchimp_process_webhook().
*/
function mailchimp_process_webhook_access($key) {
return $key == mailchimp_webhook_key();
}
/**
* Process a webhook post from MailChimp.
*/
function mailchimp_process_webhook() {
$data = $_POST['data'];
$type = $_POST['type'];
switch ($type) {
case 'unsubscribe':
case 'profile':
case 'cleaned':
mailchimp_cache_clear_user($data['list_id'], $data['email']);
mailchimp_set_memberinfo($data['list_id'], $data['email']);
break;
case 'upemail':
mailchimp_cache_clear_user($data['list_id'], $data['old_email']);
mailchimp_set_memberinfo($data['list_id'], $data['new_email']);
break;
case 'campaign':
mailchimp_cache_clear_list_activity($data['list_id']);
mailchimp_cache_clear_campaign($data['id']);
break;
}
// Allow other modules to act on a webhook.
module_invoke_all('mailchimp_process_webhook', $type, $data);
// Log event:
watchdog('mailchimp', 'Webhook type @type has been processed.', array(
'@type' => $type,
), WATCHDOG_INFO);
}
/**
* Generate a key to include in the webhook url based on a hash.
*
* @return string
* The key.
*/
function mailchimp_webhook_key() {
return drupal_hash_base64($GLOBALS['base_url'] . drupal_get_private_key() . drupal_get_hash_salt());
}
/**
* Generate the webhook endpoint URL.
*
* @return string
* The endpoint URL.
*/
function mailchimp_webhook_url() {
return $GLOBALS['base_url'] . '/mailchimp/webhook/' . mailchimp_webhook_key();
}
/**
* Helper function used by uasort() to sort lists alphabetically by name.
*
* @param array $a
* An array representing the first list.
* @param array $b
* An array representing the second list.
*
* @return int
* One of the values -1, 0, 1
*/
function _mailchimp_list_cmp($a, $b) {
if ($a['name'] == $b['name']) {
return 0;
}
return $a['name'] < $b['name'] ? -1 : 1;
}
/**
* Wrapper around MCAPI::campaigns() to return data for a given campaign.
*
* Data is stored in the temporary cache.
*
* @param string $campaign_id
* @param bool $reset
*
* @return mixed
* Array of campaign data or NULL if not found.
*/
function mailchimp_get_campaign_data($campaign_id, $reset = FALSE) {
$cache = $reset ? NULL : cache_get('mailchimp_campaign_' . $campaign_id);
// Return cached lists:
if ($cache) {
$campaign_data = $cache->data;
}
else {
$q = mailchimp_get_api_object();
$filters = array(
'campaign_id' => $campaign_id,
);
$result_sandwich = $q
->campaigns($filters);
$campaign_data = $result_sandwich['data'][0];
cache_set('mailchimp_campaign_' . $campaign_id, $campaign_data, 'cache', CACHE_TEMPORARY);
}
return $campaign_data;
}
/**
* Wrapper around MCAPI::campaignsForEmail().
*
* Returns all IDs of campaigns that have included a given email address.
*
* @param string $email
*
* @return array
* campaign IDs.
*/
function mailchimp_get_campaigns_for_email($email) {
$q = mailchimp_get_api_object();
$campaign_list = $q
->campaignsForEmail($email);
return $campaign_list;
}
/**
* Returns an array of lists that the user has been a member of.
*
* Includes a value indicating whether they are currently a subscribed or not.
*
* @param string $email
*
* @return array
* Containing 2 arrays -- one ('lists') of all lists that have made use of
* this email address (list_id -> list_data[]). One ('campaigns') of all
* campaigns that have included this email (campaign_id -> campaign_data[])
*
* We include the campaign data because we need it to get accurate list
* activity history anyway, and we want to keep the data handy to avoid
* excessive API calls.
*/
function mailchimp_get_lists_by_email($email) {
$campaign_ids = mailchimp_get_campaigns_for_email($email);
$lists = mailchimp_get_lists();
$filtered_lists = array();
if ($campaign_ids) {
// Iterate through campaigns, add each campaign's list as array index/value.
foreach ($campaign_ids as $campaign_id) {
$campaign_data = mailchimp_get_campaign_data($campaign_id);
$filtered_lists['lists'][$campaign_data['list_id']] = $lists[$campaign_data['list_id']];
$filtered_lists['campaigns'][$campaign_id] = $campaign_data;
}
}
return $filtered_lists;
}
Functions
Name | Description |
---|---|
mailchimp_cache_clear_campaign | Clear a mailchimp activity cache. |
mailchimp_cache_clear_list_activity | Clear a mailchimp activity cache. |
mailchimp_cache_clear_user | Clear a mailchimp user memberinfo cache. |
mailchimp_flush_caches | Implements hook_flush_caches(). |
mailchimp_get_api_object | Get a Mailchimp API object for communication with the mailchimp server. |
mailchimp_get_campaigns_for_email | Wrapper around MCAPI::campaignsForEmail(). |
mailchimp_get_campaign_data | Wrapper around MCAPI::campaigns() to return data for a given campaign. |
mailchimp_get_list | Wrapper around mailchimp_get_lists() to return a single list. |
mailchimp_get_lists | Return all MailChimp lists for a given key. Lists are stored in the cache. |
mailchimp_get_lists_by_email | Returns an array of lists that the user has been a member of. |
mailchimp_get_memberinfo | Get the MailChimp memberinfo for a given email address and list. |
mailchimp_is_subscribed | Check if the given email is subscribed to the given list. |
mailchimp_libraries_info | Implements hook_libraries_info(). |
mailchimp_menu | Implements hook_menu(). |
mailchimp_permission | Implements hook_permission(). |
mailchimp_process_webhook | Process a webhook post from MailChimp. |
mailchimp_process_webhook_access | Access callback for mailchimp_process_webhook(). |
mailchimp_set_memberinfo | Sets the member info in the cache. |
mailchimp_subscribe_user | Subscribe a user to a given list. |
mailchimp_unsubscribe_user | Unsubscribe a user from the given list. |
mailchimp_update_user | Update a user in a given list. |
mailchimp_webhook_key | Generate a key to include in the webhook url based on a hash. |
mailchimp_webhook_url | Generate the webhook endpoint URL. |
_mailchimp_list_cmp | Helper function used by uasort() to sort lists alphabetically by name. |