garancia/modules/mailchimpsync/mailchimpsync.php
2016-10-10 15:24:25 +02:00

772 lines
23 KiB
PHP
Executable File

<?php
if (!defined('_PS_VERSION_'))
exit;
if (!class_exists('Mailchimp'))
include_once _PS_MODULE_DIR_.'mailchimpsync/libraries/Mailchimp.php';
class MailchimpSync extends Module
{
public function __construct()
{
$this->name = 'mailchimpsync';
$this->version = '2.0.3';
$this->author = 'Sébastien Jousse';
$this->tab = 'advertising_marketing';
$this->module_key = '56bf075ed4d7cbc0ffe5cecdf05bf480';
$this->ps_versions_compliancy = array('min' => '1.5', 'max' => '1.6');
$this->need_instance = 0;
$this->bootstrap = true;
parent::__construct();
$this->displayName = $this->l('Mailchimp Sync');
$this->description = $this->l('Synchronize automatically your list of subscribers in Prestashop with your Mailchimp account, and the reverse too.');
$this->confirmUninstall = $this->l('Are you sure you want to uninstall this module ? All your settings will be lost.');
if (!$this->isCurl())
$this->_errors[] = $this->l('This module needs the cUrl extension.');
if (Configuration::get('MAILCHIMP_LIST_ID') == 0)
$this->warning = $this->l('You have not yet set your Mailchimp default list.');
if (Configuration::get('MAILCHIMP_API_KEY') == '')
$this->warning = $this->l('You have not yet set your Mailchimp API key.');
}
public function install()
{
if (!parent::install()
|| !$this->isCurl()
|| !Configuration::updateValue('MAILCHIMP_WEBHOOK_TOKEN', Tools::strtoupper(Tools::passwdGen(16)))
|| !Configuration::updateValue('MAILCHIMP_API_KEY', '')
|| !Configuration::updateValue('MAILCHIMP_LIST_ID', 0)
|| !Configuration::updateValue('MAILCHIMP_GROUPING_ID', 0)
|| !Configuration::updateValue('MAILCHIMP_GROUP_NAME', '')
|| !Configuration::updateValue('MAILCHIMP_DOUBLE_OPTIN', true)
|| !Configuration::updateValue('MAILCHIMP_SEND_WELCOME', true)
|| !Configuration::updateValue('MAILCHIMP_DELETE_MEMBER', false)
|| !Configuration::updateValue('MAILCHIMP_SEND_GOODBYE', true)
|| !Configuration::updateValue('MAILCHIMP_SEND_NOTIFY', true)
|| !$this->registerHook('actionCustomerAccountAdd')
|| !$this->registerHook('actionObjectCustomerUpdateAfter')
|| !$this->registerHook('displayHeader'))
return false;
return true;
}
public function uninstall()
{
if (!Configuration::deleteByName('MAILCHIMP_WEBHOOK_TOKEN')
|| !Configuration::deleteByName('MAILCHIMP_API_KEY')
|| !Configuration::deleteByName('MAILCHIMP_LIST_ID')
|| !Configuration::deleteByName('MAILCHIMP_GROUPING_ID')
|| !Configuration::deleteByName('MAILCHIMP_GROUP_NAME')
|| !Configuration::deleteByName('MAILCHIMP_DOUBLE_OPTIN')
|| !Configuration::deleteByName('MAILCHIMP_SEND_WELCOME')
|| !Configuration::deleteByName('MAILCHIMP_DELETE_MEMBER')
|| !Configuration::deleteByName('MAILCHIMP_SEND_GOODBYE')
|| !Configuration::deleteByName('MAILCHIMP_SEND_NOTIFY')
|| !$this->deleteWebhook()
|| !$this->unregisterHook('displayHeader')
|| !$this->unregisterHook('actionObjectCustomerUpdateAfter')
|| !$this->unregisterHook('actionCustomerAccountAdd')
|| !parent::uninstall())
return false;
return true;
}
private function addWebhook()
{
$list_id = Configuration::get('MAILCHIMP_LIST_ID');
if ($this->isConfigured() && $list_id !== '0')
{
$token = Configuration::get('MAILCHIMP_WEBHOOK_TOKEN');
$webhook_url = Context::getContext()->link->getModuleLink($this->name, 'webhook', array('token' => $token));
$mailchimp = $this->getClient();
try {
$response = $mailchimp->lists->webhookAdd($list_id, $webhook_url, array('subscribe' => true, 'unsubscribe' => true));
}
catch (Mailchimp_Error $exception) {
return false;
}
return true;
}
return false;
}
private function deleteWebhook()
{
$list_id = Configuration::get('MAILCHIMP_LIST_ID');
if ($this->isConfigured() && $list_id !== '0')
{
$token = Configuration::get('MAILCHIMP_WEBHOOK_TOKEN');
$webhook_url = Context::getContext()->link->getModuleLink($this->name, 'webhook', array('token' => $token));
$mailchimp = $this->getClient();
try {
$response = $mailchimp->lists->webhookDel($list_id, $webhook_url);
}
catch (Mailchimp_Error $exception) {
return false;
}
return true;
}
return true;
}
private function testAPI($api_key)
{
try {
$mailchimp = $this->getClient($api_key);
$response = $mailchimp->helper->ping();
return ($response['msg'] == "Everything's Chimpy!");
}
catch (Mailchimp_Error $exception) {
return false;
}
}
private function isConfigured()
{
return Configuration::get('MAILCHIMP_API_KEY') != null;
}
public function getContent()
{
$output = null;
// API key
if (Tools::isSubmit('submitKey'))
{
$api_key = Tools::getValue('MAILCHIMP_API_KEY');
if (!$api_key
|| empty($api_key)
|| !$this->testAPI($api_key))
$output .= $this->displayError($this->l('Invalid API key'));
else
{
Configuration::updateValue('MAILCHIMP_API_KEY', $api_key);
$output .= $this->displayConfirmation($this->l('Settings updated'));
}
}
// List
if (Tools::isSubmit('submitList'))
{
$list_id = Tools::getValue('MAILCHIMP_LIST_ID', '0');
if (empty($list_id) || $list_id === '0')
$output .= $this->displayError($this->l('Invalid list'));
else
{
// delete existing webhook
if (Configuration::get('MAILCHIMP_LIST_ID'))
$this->deleteWebhook();
Configuration::updateValue('MAILCHIMP_LIST_ID', $list_id);
Configuration::updateValue('MAILCHIMP_GROUPING_ID', '0');
Configuration::updateValue('MAILCHIMP_GROUP_NAME', '');
$this->addWebhook();
$output .= $this->displayConfirmation($this->l('Settings updated'));
}
}
// Group title
if (Tools::isSubmit('submitGroupTitle'))
{
$grouping_id = Tools::getValue('grouping_id');
if ($grouping_id !== false)
Configuration::updateValue('MAILCHIMP_GROUPING_ID', $grouping_id);
else
$output .= $this->displayError($this->l('Invalid group title'));
$group_name = Tools::getValue('group_name');
if ($group_name !== false)
Configuration::updateValue('MAILCHIMP_GROUP_NAME', $group_name);
else
$output .= $this->displayError($this->l('Invalid group name'));
}
// Settings
if (Tools::isSubmit('submitSettings'))
{
$double_optin = Tools::getValue('MAILCHIMP_DOUBLE_OPTIN');
$send_welcome = Tools::getValue('MAILCHIMP_SEND_WELCOME');
$delete_member = Tools::getValue('MAILCHIMP_DELETE_MEMBER');
$send_goodbye = Tools::getValue('MAILCHIMP_SEND_GOODBYE');
$send_notify = Tools::getValue('MAILCHIMP_SEND_NOTIFY');
if ($double_optin === false
|| $send_welcome === false
|| $delete_member === false
|| $send_goodbye === false
|| $send_notify === false)
$output .= $this->displayError($this->l('Invalid settings'));
else
{
Configuration::updateValue('MAILCHIMP_DOUBLE_OPTIN', $double_optin);
Configuration::updateValue('MAILCHIMP_SEND_WELCOME', $send_welcome);
Configuration::updateValue('MAILCHIMP_DELETE_MEMBER', $delete_member);
Configuration::updateValue('MAILCHIMP_SEND_GOODBYE', $send_goodbye);
Configuration::updateValue('MAILCHIMP_SEND_NOTIFY', $send_notify);
$output .= $this->displayConfirmation($this->l('Settings updated'));
}
}
return $output.$this->displayForm();
}
private function getClient($api_key = '')
{
if ($api_key == '')
{
if (!$this->isConfigured())
return null;
$api_key = Configuration::get('MAILCHIMP_API_KEY');
}
$mailchimp = new Mailchimp($api_key, array(
'ssl_verifypeer' => false
));
return $mailchimp;
}
private function getLists()
{
if (!$this->isConfigured())
return array();
$mailchimp = $this->getClient();
try {
$response = $mailchimp->lists->getList();
$lists = $response['data'];
return $lists;
}
catch (Mailchimp_Error $exception) {
return array();
}
}
private function getGroupings()
{
if (Configuration::get('MAILCHIMP_LIST_ID') !== '0')
{
$mailchimp = $this->getClient();
try
{
$groupings = $mailchimp->lists->interestGroupings(Configuration::get('MAILCHIMP_LIST_ID'));
return $groupings;
}
catch (Mailchimp_Error $exception)
{
return array();
}
}
return array();
}
public function displayForm()
{
// Get default language
$default_lang = (int)Configuration::get('PS_LANG_DEFAULT');
$fields_form = array();
// API key
$fields_form[]['form'] = array(
'legend' => array(
'title' => $this->l('API key'),
),
'description' => $this->l('You must have a MailChimp account. You can create one on their website : ')
.'<a href="http://eepurl.com/-dfjz" target="_blank">http://mailchimp.com/</a>',
'input' => array(
array(
'type' => 'text',
'label' => $this->l('Mailchimp API key'),
'desc' => $this->l('Example: 123456789abcdef0123456789abcdef0-us2')
.' <a href="http://eepurl.com/im9k" target="_blank">http://eepurl.com/im9k</a>',
'name' => 'MAILCHIMP_API_KEY',
'size' => 45,
'required' => true
)
),
'submit' => array(
'title' => $this->l('Save'),
'name' => 'submitKey',
'class' => 'button'
)
);
// List
$lists = $this->getLists();
$fields_form[]['form'] = array(
'legend' => array(
'title' => $this->l('Default list'),
),
'input' => array(
array(
'type' => 'select',
'label' => $this->l('Mailchimp list'),
'desc' => $this->l('How to create one:').' <a href="http://eepurl.com/gOHY" target="_blank">http://eepurl.com/gOHY</a>',
'name' => 'MAILCHIMP_LIST_ID',
'options' => array(
'default' => array(
'label' => $this->l('Select a list'),
'value' => 0
),
'query' => $lists,
'id' => 'id',
'name' => 'name',
),
'required' => true
)
),
'submit' => array(
'title' => $this->l('Save'),
'name' => 'submitList',
'class' => 'button'
)
);
// Interest groups
$groupings = $this->getGroupings();
//TODO
/*
<fieldset>
<legend>{l s='Mailchimp default group title' mod='mailchimpsync'}</legend>
<label>{l s='Mailchimp group title' mod='mailchimpsync'}:</label>
<div class="margin-form">
<select id="grouping_id" name="grouping_id" onchange="populate_groups();">
<option value="0">({l s='Select a group title' mod='mailchimpsync'})</option>
{foreach from=$MAILCHIMP_GROUPINGS item=grouping}
<option value="{$grouping.id}" {if $MAILCHIMP_GROUPING_ID == $grouping.id}selected="selected"{/if}>{$grouping.name}</option>
{/foreach}
</select>
<select id="group_name" name="group_name">
<option value="0">({l s='Select a group name' mod='mailchimpsync'})</option>
{if {$MAILCHIMP_GROUP_NAME} != ''}
{foreach from=$MAILCHIMP_GROUPINGS item=grouping}
{if $grouping.id == $MAILCHIMP_GROUPING_ID}
{foreach from=$grouping.groups item=group}
<option value="{$group.name}" {if $MAILCHIMP_GROUP_NAME == $group.name}selected="selected"{/if}>{$group.name}</option>
{/foreach}
{/if}
{/foreach}
{/if}
</select>
<p class="clear">{l s='How to create one:' mod='mailchimpsync'}<a href="http://eepurl.com/gWOb" target="_blank">http://eepurl.com/gWOb</a></p>
</div>
<input type="submit" name="submitGroupTitle" value="{l s='Save' mod='mailchimpsync'}" class="button" />
</fieldset>
<script type="text/javascript">
var attrs = new Array();
{foreach from=$MAILCHIMP_GROUPINGS item=grouping}
attrs[{$grouping.id}] = new Array(
{foreach from=$grouping.groups item=group name=foo}
{if $smarty.foreach.foo.last}
"{$group.name}"
{else}
"{$group.name}",
{/if}
{/foreach}
);
{/foreach}
function populate_groups() {
var attr_grouping = getE("grouping_id");
if (!attr_grouping)
return;
var attr_groupname = getE("group_name");
var number = attr_grouping.options.length ? attr_grouping.options[attr_grouping.selectedIndex].value : 0;
if (!number) {
attr_groupname.options.length = 0;
attr_groupname.options[0] = new Option("---", 0);
return;
}
if (number == 0) {
attr_groupname.options.length = 0;
attr_groupname.options[0] = new Option("---", 0);
return;
}
var list = attrs[number];
attr_groupname.options.length = 0;
attr_groupname.options[0] = new Option("---", 0);
for(i = 0; i < list.length; i++) {
attr_groupname.options[i+1] = new Option(list[i], list[i]);
}
}
</script>
*/
// Settings
$fields_form[]['form'] = array(
'legend' => array(
'title' => $this->l('Settings'),
),
'input' => array(
array(
'type' => (version_compare(_PS_VERSION_, '1.6') < 0) ? 'radio' : 'switch',
'label' => $this->l('Double Opt in', get_class($this), null, false),
'name' => 'MAILCHIMP_DOUBLE_OPTIN',
'required' => false,
'class' => 't',
'is_bool' => true,
'values' => array(
array(
'id' => 'double_option_on',
'value' => 1,
'label' => $this->l('Enabled', get_class($this), null, false)
),
array(
'id' => 'double_option_off',
'value' => 0,
'label' => $this->l('Disabled', get_class($this), null, false)
)
),
//'desc' => $this->l('Enable or disable the prepaid account.', get_class($this), null, false)
),
array(
'type' => (version_compare(_PS_VERSION_, '1.6') < 0) ? 'radio' : 'switch',
'label' => $this->l('Send welcome message', get_class($this), null, false),
'name' => 'MAILCHIMP_SEND_WELCOME',
'required' => false,
'class' => 't',
'is_bool' => true,
'values' => array(
array(
'id' => 'send_welcome_on',
'value' => 1,
'label' => $this->l('Enabled', get_class($this), null, false)
),
array(
'id' => 'send_welcome_off',
'value' => 0,
'label' => $this->l('Disabled', get_class($this), null, false)
)
),
//'desc' => $this->l('Enable or disable the prepaid account.', get_class($this), null, false)
),
array(
'type' => (version_compare(_PS_VERSION_, '1.6') < 0) ? 'radio' : 'switch',
'label' => $this->l('Delete member on unsubscribe', get_class($this), null, false),
'name' => 'MAILCHIMP_DELETE_MEMBER',
'required' => false,
'class' => 't',
'is_bool' => true,
'values' => array(
array(
'id' => 'delete_member_on',
'value' => 1,
'label' => $this->l('Enabled', get_class($this), null, false)
),
array(
'id' => 'delete_member_off',
'value' => 0,
'label' => $this->l('Disabled', get_class($this), null, false)
)
),
//'desc' => $this->l('Enable or disable the prepaid account.', get_class($this), null, false)
),
array(
'type' => (version_compare(_PS_VERSION_, '1.6') < 0) ? 'radio' : 'switch',
'label' => $this->l('Send goodbye message', get_class($this), null, false),
'name' => 'MAILCHIMP_SEND_GOODBYE',
'required' => false,
'class' => 't',
'is_bool' => true,
'values' => array(
array(
'id' => 'send_goodbye_on',
'value' => 1,
'label' => $this->l('Enabled', get_class($this), null, false)
),
array(
'id' => 'send_goodbye_off',
'value' => 0,
'label' => $this->l('Disabled', get_class($this), null, false)
)
),
//'desc' => $this->l('Enable or disable the prepaid account.', get_class($this), null, false)
),
array(
'type' => (version_compare(_PS_VERSION_, '1.6') < 0) ? 'radio' : 'switch',
'label' => $this->l('Send notification message', get_class($this), null, false),
'name' => 'MAILCHIMP_SEND_NOTIFY',
'required' => false,
'class' => 't',
'is_bool' => true,
'values' => array(
array(
'id' => 'send_notify_on',
'value' => 1,
'label' => $this->l('Enabled', get_class($this), null, false)
),
array(
'id' => 'send_notify_off',
'value' => 0,
'label' => $this->l('Disabled', get_class($this), null, false)
)
),
//'desc' => $this->l('Enable or disable the prepaid account.', get_class($this), null, false)
),
),
'submit' => array(
'title' => $this->l('Save'),
'name' => 'submitSettings',
'class' => 'button'
)
);
$helper = new HelperForm();
// Module, token and currentIndex
$helper->module = $this;
$helper->name_controller = $this->name;
$helper->token = Tools::getAdminTokenLite('AdminModules');
$helper->currentIndex = AdminController::$currentIndex.'&configure='.$this->name;
// Language
$helper->default_form_language = $default_lang;
$helper->allow_employee_form_lang = $default_lang;
// Title and toolbar
$helper->title = $this->displayName;
$helper->show_toolbar = true; // false -> remove toolbar
$helper->toolbar_scroll = true; // yes - > Toolbar is always visible on the top of the screen.
$helper->submit_action = 'submit'.$this->name;
$helper->toolbar_btn = array();
// Load current value
$helper->fields_value['MAILCHIMP_API_KEY'] = Configuration::get('MAILCHIMP_API_KEY');
$helper->fields_value['MAILCHIMP_LIST_ID'] = Configuration::get('MAILCHIMP_LIST_ID');
$helper->fields_value['MAILCHIMP_GROUPING_ID'] = Configuration::get('MAILCHIMP_GROUPING_ID');
$helper->fields_value['MAILCHIMP_GROUP_NAME'] = Configuration::get('MAILCHIMP_GROUP_NAME');
$helper->fields_value['MAILCHIMP_DOUBLE_OPTIN'] = Configuration::get('MAILCHIMP_DOUBLE_OPTIN');
$helper->fields_value['MAILCHIMP_SEND_WELCOME'] = Configuration::get('MAILCHIMP_SEND_WELCOME');
$helper->fields_value['MAILCHIMP_DELETE_MEMBER'] = Configuration::get('MAILCHIMP_DELETE_MEMBER');
$helper->fields_value['MAILCHIMP_SEND_GOODBYE'] = Configuration::get('MAILCHIMP_SEND_GOODBYE');
$helper->fields_value['MAILCHIMP_SEND_NOTIFY'] = Configuration::get('MAILCHIMP_SEND_NOTIFY');
return $helper->generateForm($fields_form);
}
private function prepareHook()
{
if (Tools::isSubmit('submitNewsletter')
|| Tools::isSubmit('blockpopupnewsletter-email'))
{
$email = Tools::getValue('email');
if (empty($email) || !Validate::isEmail($email))
return $this->error = $this->l('Invalid email address');
/* Unsubscription */
if (Tools::getValue('action') == '1')
return $this->unregister($email);
/* Subscription */
if (Tools::getValue('action') == '0')
return $this->register($email, array('optin_ip' => Tools::getRemoteAddr()));
}
if (Tools::isSubmit('submitMessage')){
$email = Tools::getValue('customer_email');
if (!empty($email) && Tools::getValue('newsletter') === true){
return $this->register($email, array('optin_ip' => Tools::getRemoteAddr()));
}
}
}
public function registerPopup($email, $data) {
$this->register($email, $data);
}
public function register($email, $data)
{
$list_id = Configuration::get('MAILCHIMP_LIST_ID');
if (!$this->isConfigured() || $list_id === '0')
return false;
$mailchimp = $this->getClient();
$merge_vars = $data;
// add language
if (!array_key_exists('mc_language', $merge_vars))
$merge_vars['mc_language'] = $this->context->language->iso_code;
// add grouping of interest
if (Configuration::get('MAILCHIMP_GROUPING_ID') != '0' && Configuration::get('MAILCHIMP_GROUP_NAME') != '')
{
$merge_vars['GROUPINGS'] = array(
array(
'id' => Configuration::get('MAILCHIMP_GROUPING_ID'),
'groups' => Configuration::get('MAILCHIMP_GROUP_NAME'),
),
);
}
$double_optin = Configuration::get('MAILCHIMP_DOUBLE_OPTIN');
$send_welcome = Configuration::get('MAILCHIMP_SEND_WELCOME');
try {
$response = $mailchimp->lists->subscribe($list_id, array('email' => $email), $merge_vars, 'html', $double_optin, true, false, $send_welcome);
return (array_key_exists('email', $response));
}
catch (Mailchimp_Error $exception) {
p($exception);
return false;
}
}
private function unregister($email)
{
$list_id = Configuration::get('MAILCHIMP_LIST_ID');
if (!$this->isConfigured() || $list_id === '0')
return false;
$mailchimp = $this->getClient();
$delete_member = Configuration::get('MAILCHIMP_DELETE_MEMBER');
$send_goodbye = Configuration::get('MAILCHIMP_SEND_GOODBYE');
$send_notify = Configuration::get('MAILCHIMP_SEND_NOTIFY');
try {
$response = $mailchimp->lists->unsubscribe($list_id, array('email' => $email), $delete_member, $send_goodbye, $send_notify);
return (array_key_exists('complete', $response));
}
catch (Mailchimp_Error $exception) {
return false;
}
}
public function hookActionCustomerAccountAdd($params)
{
$new_customer = $params['newCustomer'];
if (!Validate::isLoadedObject($new_customer))
return false;
$newsletter = $new_customer->newsletter;
$email = $new_customer->email;
if (!$newsletter || !Validate::isEmail($email))
return true;
$merge_vars = array(
'FNAME' => $new_customer->firstname,
'LNAME' => $new_customer->lastname,
'optin_ip' => $new_customer->ip_registration_newsletter,
'optin_time' => $new_customer->newsletter_date_add,
);
return $this->register($email, $merge_vars);
}
public function hookActionObjectCustomerUpdateAfter($params)
{
$customer = $params['object'];
if (!Validate::isLoadedObject($customer))
return false;
if (!isset($customer->newsletter))
return false;
if ($customer->newsletter == 0)
return $this->unregister($customer->email);
else
{
$merge_vars = array(
'FNAME' => $customer->firstname,
'LNAME' => $customer->lastname,
'optin_ip' => $customer->ip_registration_newsletter,
'optin_time' => $customer->newsletter_date_add,
);
return $this->register($customer->email, $merge_vars);
}
}
public function hookDisplayHeader($params)
{
return $this->prepareHook();
}
public function hookDisplayLeftColumn($params)
{
return $this->hookDisplayHeader($params);
}
public function hookDisplayRightColumn($params)
{
return $this->hookDisplayHeader($params);
}
public function hookDisplayFooter($params)
{
return $this->hookDisplayHeader($params);
}
public function confirmEvent()
{
$token = Configuration::get('MAILCHIMP_WEBHOOK_TOKEN');
if ($token === false)
return false;
if (!Tools::getIsset('token')
|| Tools::getValue('token') != $token)
return false;
if (!Tools::getIsset('type'))
return false;
$data = Tools::getValue('data');
switch (Tools::getValue('type'))
{
case 'unsubscribe':
if (!array_key_exists('email', $data))
return false;
$c = new Customer();
if ($c->getByEmail($data['email']))
{
$c->newsletter = 0;
$c->ip_registration_newsletter = null;
$c->newsletter_date_add = null;
$c->update();
}
break;
case 'subscribe':
if (!array_key_exists('email', $data)
|| !array_key_exists('ip_opt', $data))
return false;
$c = new Customer();
if ($c->getByEmail($data['email']))
{
$c->newsletter = 1;
$c->ip_registration_newsletter = $data['ip_opt'];
$c->newsletter_date_add = Tools::getValue('fired_at');
$c->update();
}
break;
}
return true;
}
/* Check if cUrl extension is enabled */
private function isCurl()
{
return function_exists('curl_version');
}
}