'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 $list_id * @param $email * * @return bool */ function mailchimp_is_subscribed($list_id, $email) { $subscribed = FALSE; $memberinfo = mailchimp_get_memberinfo($list_id, $email); 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) { 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 object $list * @param string $email * @param bool $message * @param object $mcapi * @param book $delete * Indicates whether an email should be deleted or just unsubscribed. * @return bool */ 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 ($message && $success) { 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. */ function mailchimp_get_api_object() { $q = new MCAPI(variable_get('mailchimp_api_key', '')); // set the timeout to something reasonsable to avoid taking down the Drupal site $q->setTimeout(60); // specify if a secure connection should be used wit 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 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; } // Query lists from the MC API and store in cache 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; } } } 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 * * @return array list */ 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 */ 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; } // Query lists from the MC API and store in cache 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 $list_id * @param $email */ function mailchimp_cache_clear_user($list_id, $email) { cache_clear_all($list_id . '-' . $email, 'cache_mailchimp_user'); } /** * Implements hook_flush_caches(). */ function mailchimp_flush_caches() { return array('cache_mailchimp_user'); } /** * Access callback for mailchimp_process_webhook(). * * @param string $key * * @return bool */ function mailchimp_process_webhook_access($key) { return $key == mailchimp_webhook_key(); } /** * Process a webhook post from MailChimp */ function mailchimp_process_webhook() { $data = $_POST['data']; switch ($_POST['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; } // log event watchdog('mailchimp', 'Webhook type !type has been processed.', array('!type' => $_POST['type']), WATCHDOG_INFO ); } /** * Generate a key to include in the webhook url based on a hash. * * @param string $list_id * * @return string */ function mailchimp_webhook_key() { return md5($GLOBALS['base_url']); } /** * Generate the webhook endpoint URL. * * @param string $list_id * * @return string */ function mailchimp_webhook_url() { return $GLOBALS['base_url'] . '/mailchimp/webhook/' . mailchimp_webhook_key(); }