* @copyright 2007-2015 PrestaShop SA * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) * International Registered Trademark & Property of PrestaShop SA */ require _PS_MODULE_DIR_.'mailchimpsync/vendor/autoload.php'; class MailChimpClient { const STATUS_PENDING = 'pending'; const STATUS_SUBSCRIBED = 'subscribed'; const STATUS_UNSUBSCRIBED = 'unsubscribed'; const STATUS_CLEANED = 'cleaned'; const SOURCE_USER = 'user'; const SOURCE_ADMIN = 'admin'; const SOURCE_API = 'api'; const EVENT_SUBSCRIBE = 'subscribe'; const EVENT_UNSUBSCRIBE = 'unsubscribe'; private $api_root = 'https://api.mailchimp.com/3.0'; private $api_key = ''; private $headers = array(); private $options = array(); /** * @param string $api_key */ public function __construct($api_key) { $this->api_key = $api_key; $dc = 'us1'; if (strstr($this->api_key, '-')) { list(, $dc) = explode('-', $this->api_key, 2); if (!$dc) { $dc = 'us1'; } } $this->api_root = str_replace('https://api', 'https://'.$dc.'.api', $this->api_root); $this->headers = array( 'User-Agent' => 'MailChimp-PHP/3.0', 'Content-Type' => 'application/json' ); $this->options = array( 'auth' => array('apikey', $api_key) ); } /** * @return bool * @throws Requests_Exception */ public function ping() { $url = $this->api_root.'/'; $response = Requests::get($url, $this->headers, $this->options); $response->throw_for_status(); return $response->success; } /** * get all lists * @return array * @throws Requests_Exception */ public function getLists() { $url = $this->api_root.'/lists/?count=1000'; $response = Requests::get($url, $this->headers, $this->options); $response->throw_for_status(); $result = Tools::jsonDecode($response->body, true); return $result; } /** * get all webhooks * @return array * @throws Requests_Exception */ public function webhookList($list_id) { $url = $this->api_root.'/lists/'.$list_id.'/webhooks'; $response = Requests::get($url, $this->headers, $this->options); $response->throw_for_status(); $result = Tools::jsonDecode($response->body, true); return $result; } /** * add webhook * @param string $list_id * @param string $webhook_url * @param array $events * @return bool * @throws Requests_Exception */ public function webhookAdd($list_id, $webhook_url, $events) { $request = array( 'url' => $webhook_url, 'events' => $events, 'sources' => array( MailChimpClient::SOURCE_USER => true, MailChimpClient::SOURCE_ADMIN => true, ) ); $url = $this->api_root.'/lists/'.$list_id.'/webhooks'; $response = Requests::post($url, $this->headers, Tools::jsonEncode($request), $this->options); $response->throw_for_status(); return $response->success; } /** * delete webhook * @param string $list_id * @param string $webhook_url * @return bool * @throws Requests_Exception */ public function webhookDel($list_id, $webhook_url) { $webhooks = $this->webhookList($list_id); $webhooks_to_delete = array_filter($webhooks['webhooks'], function ($webhook) use ($webhook_url) { return $webhook['url'] == $webhook_url; }); if (count($webhooks_to_delete) == 0) { return true; } foreach ($webhooks_to_delete as $webhook) { $url = $this->api_root . '/lists/' . $list_id . '/webhooks/' . $webhook['id']; $response = Requests::delete($url, $this->headers, $this->options); } $response->throw_for_status(); return $response->success; } /** * get details of list * @param string $list_id * @return array * @throws Requests_Exception */ public function getList($list_id) { $url = $this->api_root.'/lists/'.$list_id; $response = Requests::get($url, $this->headers, $this->options); $response->throw_for_status(); $result = Tools::jsonDecode($response->body, true); return $result; } /** * ckeck subscriber's status * @param string $list_id * @param string $email * @return string {subscribed|unsubscribed|pending|cleaned} * @throws Requests_Exception */ public function checkStatus($list_id, $email) { $url = $this->api_root.'/lists/'.$list_id.'/members/'. self::hash($email); $response = Requests::get($url, $this->headers, $this->options); $response->throw_for_status(); $result = Tools::jsonDecode($response->body, true); return $result['status']; } /** * add contact to list * @param string $list_id * @param string $email * @param array $merge_vars * @param array $data * @param bool $double_optin * @param bool $force * @return bool * @throws Requests_Exception */ public function subContact($list_id, $email, $merge_vars, $data, $double_optin, $force = false) { $request = array( 'email_address' => $email, 'status_if_new' => $double_optin ? MailChimpClient::STATUS_PENDING : MailChimpClient::STATUS_SUBSCRIBED, ); if ($force) { $request['status'] = MailChimpClient::STATUS_SUBSCRIBED; } if (count($merge_vars) > 0) { $request['merge_fields'] = $merge_vars; } if (array_key_exists('mc_language', $data) && !empty($data['mc_language'])) { $request['language'] = $data['mc_language']; } if (array_key_exists('optin_ip', $data) && !empty($data['optin_ip'])) { $request['ip_signup'] = $data['optin_ip']; } if (array_key_exists('optin_time', $data) && !empty($data['optin_time'])) { $request['timestamp_signup'] = $data['optin_time']; } $url = $this->api_root.'/lists/'.$list_id.'/members/'. self::hash($email); $response = Requests::put($url, $this->headers, Tools::jsonEncode($request), $this->options); $response->throw_for_status(); return $response->success; } /** * remove contact from list * @param string $list_id * @param string $email * @param bool $delete_member * @return bool * @throws Requests_Exception */ public function unsubContact($list_id, $email, $delete_member) { $url = $this->api_root.'/lists/'.$list_id.'/members/'. self::hash($email); if ($delete_member) { $response = Requests::delete($url, $this->headers, $this->options); } else { $data = array( 'status' => MailChimpClient::STATUS_UNSUBSCRIBED ); $response = Requests::patch($url, $this->headers, Tools::jsonEncode($data), $this->options); } $response->throw_for_status(); return $response->success; } /** * export contacts in list * @param string $list_id * @param array $subscribers * @return bool * @throws Requests_Exception */ public function exportContacts($list_id, $subscribers) { $prepareOperation = function ($subscriber) use ($list_id) { $body = array( 'email_address' => $subscriber['email'], 'status_if_new' => MailChimpClient::STATUS_SUBSCRIBED, ); $merge_fields = MailChimpClient::getMergeFields($subscriber); if (count($merge_fields) > 0) { $body['merge_fields'] = $merge_fields; } if ($subscriber['lang'] != null) { $body['language'] = $subscriber['lang']; } return array( 'method' => 'PUT', 'path' => "lists/{$list_id}/members/" . MailChimpClient::hash($subscriber['email']), 'body' => Tools::jsonEncode($body), ); }; try { $url = $this->api_root . '/batches/'; foreach (array_chunk($subscribers, 200, false) as $chunk) { $operations = array_map($prepareOperation, $chunk); $response = Requests::post( $url, $this->headers, Tools::jsonEncode(array('operations' => $operations)), $this->options ); $response->throw_for_status(); } } catch (Exception $ex) { return false; } return true; } /** * get contacts from list * @param string $list_id * @return array * @throws Requests_Exception */ public function getContacts($list_id) { $offset = 0; $page = 0; $count = 100; $fields = array('members.email_address', 'members.timestamp_signup', 'total_items', 'members.status'); $status = array('subscribed', 'unsubscribed', 'cleaned'); $subscribers = array(); do { $url = $this->api_root . '/lists/' . $list_id . '/members?offset=' . $offset . '&count='.$count.'&fields=' . implode(',', $fields) . '&status=' . implode(',', $status); $response = Requests::get($url, $this->headers, $this->options); $response->throw_for_status(); $result = Tools::jsonDecode($response->body, true); $subscribers = array_merge($subscribers, $result['members']); $offset = ++$page * $count; } while ($offset < $result['total_items']); return $subscribers; } public static function getMergeFields($subscriber) { $merge_fields = array(); if ($subscriber['firstname'] != null) { $merge_fields['FNAME'] = $subscriber['firstname']; } if ($subscriber['lastname'] != null) { $merge_fields['LNAME'] = $subscriber['lastname']; } return $merge_fields; } /** * create hash from email * @param $email * @return string */ public static function hash($email) { return md5(Tools::strtolower($email)); } }