diff --git a/CHANGELOG.md b/CHANGELOG.md
index 99fb7f6d..98f46c42 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,11 @@
# Changelog
+### 1.5.0
+
+- New feature to trigger opt-in if new customer joins with newsletter enabled. [issue #32](https://github.com/sendsmaily/smaily-prestashop-module/issues/32)
+- Fix missing template variables. [issue #33](https://github.com/sendsmaily/smaily-prestashop-module/issues/33)
+- Use PrestashopLogger for logs created by module. [issue #36](https://github.com/sendsmaily/smaily-prestashop-module/issues/36)
+
### 1.4.0
- Added RSS settings tab.
diff --git a/README.md b/README.md
index 52d3b7d1..44735cdc 100644
--- a/README.md
+++ b/README.md
@@ -53,14 +53,16 @@ All development for Smaily for Prestashop is [handled via GitHub](https://github
2. Insert your Smaily API authentication information and click **Validate** to get started.
3. Under **Customer Synchronization** tab select if you want to enable customer synchronization.
4. Select additional fields you want to synchronize (email is automatic), change cron token if you like your own.
-5. Click **Save** to save customer synchronization settings.
-6. Under **Abandoned Cart** tab select if you want to enable abandoned cart synchronization.
-7. Select autoresponder for abandoned cart.
-8. Select additional fields to send to abandoned cart template. Firstname, lastname and store-url are always added.
-9. Add delay time when cart is considered abandoned. Minimum time 15 minutes. Change cron token if you like your own.
-10. Click **Save** to save abandoned cart settings.
-11. Cron is set up to synchronize contacts when CRON-url is visited. Use host Cpanel, PrestaShop Cron tasks manager or external cron service to automate process.
-12. That's it, your PrestaShop store is now integrated with Smaily Plugin!
+5. New customers who sign up with newsletter enabled can be added to Smaily by enabling trigger opt-in on customer signup.
+6. An autoresponder can be selected for "opt-in on customer sign-up", this will only be triggered if the previous option is enabled.
+7. Click **Save** to save customer synchronization settings.
+8. Under **Abandoned Cart** tab select if you want to enable abandoned cart synchronization.
+9. Select autoresponder for abandoned cart.
+10. Select additional fields to send to abandoned cart template. Firstname, lastname and store-url are always added.
+11. Add delay time when cart is considered abandoned. Minimum time 15 minutes. Change cron token if you like your own.
+12. Click **Save** to save abandoned cart settings.
+13. Cron is set up to synchronize contacts when CRON-url is visited. Use host Cpanel, PrestaShop Cron tasks manager or external cron service to automate process.
+14. That's it, your PrestaShop store is now integrated with Smaily Plugin!
## Using Newsletter Subscription form
diff --git a/USERGUIDE.md b/USERGUIDE.md
index e906cc43..3614548b 100644
--- a/USERGUIDE.md
+++ b/USERGUIDE.md
@@ -48,7 +48,8 @@ Registered customers, who have opted for the newsletter will be added to Smaily'
1. Enable automatic customer synchronization feature under **Customer synchronization** section.
2. There is an option to import **additional fields** available from the store into Smaily to personalize newsletter emails.
3. The synchronization can be automated using the cron URL. Recommended synchronization interval is once a day or less.
-
+4. New customers who sign up with newsletter enabled can be added to Smaily, by enabling trigger opt-in on customer signup.
+5. An autoresponder can be selected for new customers who sign up with newsletter, the autoresponder won't work if the setting is disabled.

## Abandoned cart emails
diff --git a/assets/CustomerSync.png b/assets/CustomerSync.png
index 9bbc0bf0..1fc13af3 100644
Binary files a/assets/CustomerSync.png and b/assets/CustomerSync.png differ
diff --git a/controllers/front/SmailyCartCron.php b/controllers/front/SmailyCartCron.php
index 28cdc607..3758ac2c 100644
--- a/controllers/front/SmailyCartCron.php
+++ b/controllers/front/SmailyCartCron.php
@@ -51,8 +51,7 @@ private function abandonedCart()
}
// Settings.
- $autoresponder = unserialize(Configuration::get('SMAILY_CART_AUTORESPONDER'));
- $autoresponder_id = pSQL($autoresponder['id']);
+ $autoresponder_id = pSQL(Configuration::get('SMAILY_CART_AUTORESPONDER'));
$delay = pSQL(Configuration::get('SMAILY_ABANDONED_CART_TIME'));
$sync_fields = unserialize(Configuration::get('SMAILY_CART_SYNCRONIZE_ADDITIONAL'));
@@ -157,7 +156,13 @@ private function abandonedCart()
$response['result']['code'] === 101) {
$this->updateSentStatus($id_customer, $id_cart);
} else {
- $this->module->logTofile('smaily-cart.txt', Tools::jsonEncode($response));
+ $this->module->logErrorWithFormatting(
+ "Failed sending out abandoned cart email for email: %s, cart_id: %s. Smaily response code: %s, message: %s.",
+ $abandoned_cart['email'],
+ $abandoned_cart['id_cart'],
+ $response['result']['code'],
+ $response['result']['message']
+ );
}
}
echo('Abandoned carts emails sent!');
diff --git a/controllers/front/SmailyCustomerCron.php b/controllers/front/SmailyCustomerCron.php
index 9ab87455..77303b27 100644
--- a/controllers/front/SmailyCustomerCron.php
+++ b/controllers/front/SmailyCustomerCron.php
@@ -43,7 +43,7 @@ public function init()
echo('Access denied!');
die(1);
}
-
+
if ((int) Configuration::get('SMAILY_ENABLE_CRON') !== 1) {
echo('User synchronization disabled!');
die(1);
@@ -65,14 +65,14 @@ private function syncContacts()
{
$unsubscribers_synchronized = $this->removeUnsubscribers(self::UNSUBSCRIBERS_BATCH_LIMIT);
if (!$unsubscribers_synchronized) {
- $this->module->logTofile('smaily-cron.txt', 'Customer sync failed - unsubscribers are not removed');
+ $this->module->logMessageWithSeverity("Customer sync failed - unsubscribers are not removed", 1);
return false;
}
// Don't sync customers if failed to remove unsubscribers.
$subscribers_synchronized = $this->sendSubscribersToSmaily(self::SUBSCRIBERS_BATCH_LIMIT);
if (!$subscribers_synchronized) {
- $this->module->logTofile('smaily-cron.txt', 'Customer sync failed - faild to send subscribers to Smaily');
+ $this->module->logMessageWithSeverity("Customer sync failed - failed to send subscribers to Smaily", 1);
return false;
}
@@ -126,6 +126,7 @@ private function removeUnsubscribers($limit = 1000)
// Stop if error.
if (!isset($unsubscribers['success'])) {
+ $this->module->logErrorWithFormatting("Failed fetching unsubscribers.");
return false;
}
// Stop if no more subscribers.
@@ -147,6 +148,7 @@ function ($item) {
$query_result = Db::getInstance()->execute($query);
// Stop if query fails.
if ($query_result === false) {
+ $this->module->logErrorWithFormatting("Failed removing subscribed status for unsubscribers.");
return false;
}
@@ -178,6 +180,7 @@ public function sendSubscribersToSmaily($limit)
$customers = Db::getInstance()->executeS($sql);
// Stop if query fails.
if ($customers === false) {
+ $this->module->logErrorWithFormatting("Failed retrieving newsletter subscribers from DB.");
return false;
}
// Stop if no more qustomers.
@@ -195,6 +198,11 @@ public function sendSubscribersToSmaily($limit)
$response = $this->module->callApi('contact', $update_data, 'POST');
// Stop if not successful update.
if (isset($response['result']['code']) && $response['result']['code'] !== 101) {
+ $this->module->logErrorWithFormatting(
+ "Failed sending subscribers to Smaily. Smaily response code: %s, message: %s",
+ $response['result']['code'],
+ $response['result']['message']
+ );
return false;
}
diff --git a/smailyforprestashop.php b/smailyforprestashop.php
index d9a7cacc..c144f0b4 100644
--- a/smailyforprestashop.php
+++ b/smailyforprestashop.php
@@ -32,7 +32,7 @@ public function __construct()
{
$this->name = 'smailyforprestashop';
$this->tab = 'advertising_marketing';
- $this->version = '1.4.0';
+ $this->version = '1.5.0';
$this->author = 'Smaily';
$this->need_instance = 0;
$this->ps_versions_compliancy = array(
@@ -78,12 +78,16 @@ public function install()
!Configuration::updateValue('SMAILY_RSS_LIMIT', '50') ||
!Configuration::updateValue('SMAILY_RSS_SORT_BY', 'date_upd') ||
!Configuration::updateValue('SMAILY_RSS_SORT_ORDER', 'desc') ||
+ !Configuration::updateValue('SMAILY_OPTIN_ENABLED', 0) ||
+ !Configuration::updateValue('SMAILY_OPTIN_AUTORESPONDER', '') ||
// Add tab to sidebar
!$this->installTab('AdminAdmin', 'AdminSmailyforprestashopAjax', 'Smaily for PrestaShop') ||
// Add Newsletter subscription form.
!$this->registerHook('footerBefore') ||
!$this->registerHook('leftColumn') ||
- !$this->registerHook('rightColumn')
+ !$this->registerHook('rightColumn') ||
+ // User has option to trigger opt-in when customer joins store & newsletter through sign-up.
+ !$this->registerHook('actionCustomerAccountAdd')
) {
return false;
}
@@ -132,6 +136,8 @@ public function uninstall()
!Configuration::deleteByName('SMAILY_RSS_LIMIT') ||
!Configuration::deleteByName('SMAILY_RSS_SORT_BY') ||
!Configuration::deleteByName('SMAILY_RSS_SORT_ORDER') ||
+ !Configuration::deleteByName('SMAILY_OPTIN_ENABLED') ||
+ !Configuration::deleteByName('SMAILY_OPTIN_AUTORESPONDER') ||
// Remove sideTab of smaily module.
!$this->uninstallTab('AdminSmailyforprestashopAjax')
) {
@@ -164,9 +170,10 @@ public function getContent()
) {
// Disable customer sync.
Configuration::updateValue('SMAILY_ENABLE_CRON', 0);
- // Disable abandoned cart cron and remove autoresponder.
+ // Disable abandoned cart cron and remove all autoresponders.
Configuration::updateValue('SMAILY_ENABLE_ABANDONED_CART', 0);
Configuration::updateValue('SMAILY_CART_AUTORESPONDER', '');
+ Configuration::updateValue('SMAILY_OPTIN_AUTORESPONDER', '');
// Return success message.
$output .= $this->displayConfirmation($this->l('Credentials removed!'));
} else {
@@ -194,6 +201,8 @@ public function getContent()
$escaped_sync_additional[] = pSQL($value);
}
}
+ $optin_enabled = pSQL(Tools::getValue('SMAILY_OPTIN_ENABLED'));
+ $customer_join_autoresponder = pSQL(Tools::getValue('SMAILY_OPTIN_AUTORESPONDER'));
// Check if subdomain is saved to db to verify that credentials are validated.
if (empty(Configuration::get('SMAILY_SUBDOMAIN'))) {
// Display error message.
@@ -203,6 +212,8 @@ public function getContent()
Configuration::updateValue('SMAILY_ENABLE_CRON', $enable_cron);
Configuration::updateValue('SMAILY_CUSTOMER_CRON_TOKEN', $customer_cron_token);
Configuration::updateValue('SMAILY_SYNCRONIZE_ADDITIONAL', serialize($escaped_sync_additional));
+ Configuration::updateValue('SMAILY_OPTIN_ENABLED', $optin_enabled);
+ Configuration::updateValue('SMAILY_OPTIN_AUTORESPONDER', $customer_join_autoresponder);
// Display success message.
$output .= $this->displayConfirmation($this->l('Settings updated'));
}
@@ -222,17 +233,7 @@ public function getContent()
$cart_cron_token = uniqid();
}
// Abandoned cart Autoresponder
- $cart_autoresponder = pSQL((Tools::getValue('SMAILY_CART_AUTORESPONDER')));
- $cart_autoresponder = str_replace('\"', '"', $cart_autoresponder);
- // Get autoresponder array from json string.
- $cart_autoresponder = Tools::jsonDecode($cart_autoresponder);
- // Clean autoresponder for inserting to database.
- $escaped_cart_autoresponder = array();
- if (!empty($cart_autoresponder)) {
- foreach ($cart_autoresponder as $key => $value) {
- $escaped_cart_autoresponder[ pSQL($key)] = pSQL($value);
- }
- }
+ $cart_autoresponder = pSQL(Tools::getValue('SMAILY_CART_AUTORESPONDER'));
// Syncronize additional for abandoned cart template.
$cart_syncronize_additional = Tools::getValue('SMAILY_CART_SYNCRONIZE_ADDITIONAL');
$cart_escaped_sync_additional = array();
@@ -250,7 +251,7 @@ public function getContent()
$output .= $this->displayError($this->l('Select autoresponder for abandoned cart.'));
} else {
Configuration::updateValue('SMAILY_ENABLE_ABANDONED_CART', $enable_abandoned_cart);
- Configuration::updateValue('SMAILY_CART_AUTORESPONDER', serialize($escaped_cart_autoresponder));
+ Configuration::updateValue('SMAILY_CART_AUTORESPONDER', $cart_autoresponder);
Configuration::updateValue('SMAILY_ABANDONED_CART_TIME', $abandoned_cart_time);
Configuration::updateValue('SMAILY_CART_CRON_TOKEN', $cart_cron_token);
Configuration::updateValue(
@@ -308,10 +309,10 @@ public function getContent()
} else {
$cart_cron_token = uniqid();
}
+ // Get customer join autoresponder values for template.
+ $optin_autoresponder = pSQL(Configuration::get('SMAILY_OPTIN_AUTORESPONDER'));
// Get abandoned cart autoresponder values for template.
- $cart_autoresponder_for_template = pSQL((Configuration::get('SMAILY_CART_AUTORESPONDER')));
- $cart_autoresponder_for_template = str_replace('\"', '"', $cart_autoresponder_for_template);
- $cart_autoresponder_for_template = unserialize($cart_autoresponder_for_template);
+ $cart_autoresponder = pSQL(Configuration::get('SMAILY_CART_AUTORESPONDER'));
$categories = Category::getNestedCategories(null, Context::getContext()->language->id);
@@ -323,7 +324,7 @@ public function getContent()
'smaily_subdomain' => pSQL(Configuration::get('SMAILY_SUBDOMAIN')),
'smaily_username' => pSQL(Configuration::get('SMAILY_USERNAME')),
'smaily_password' => pSQL(Configuration::get('SMAILY_PASSWORD')),
- 'smaily_cart_autoresponder' => $cart_autoresponder_for_template,
+ 'smaily_cart_autoresponder' => $cart_autoresponder,
'smaily_abandoned_cart_time' => pSQL(Configuration::get('SMAILY_ABANDONED_CART_TIME')),
'smaily_syncronize_additional' => $sync_array,
'smaily_cart_syncronize_additional' => $cart_sync_array,
@@ -334,6 +335,8 @@ public function getContent()
'SmailyCustomerCron',
array('token' => $customer_cron_token)
),
+ 'smaily_customer_cron_token' => $customer_cron_token,
+ 'smaily_cart_cron_token' => $cart_cron_token,
'smaily_cart_cron_url' => Context::getContext()->link->getModuleLink(
'smailyforprestashop',
'SmailyCartCron',
@@ -344,6 +347,8 @@ public function getContent()
'smaily_rss_limit' => pSQL(Configuration::get('SMAILY_RSS_LIMIT')),
'smaily_rss_sort_by' => pSQL(Configuration::get('SMAILY_RSS_SORT_BY')),
'smaily_rss_sort_order' => pSQL(Configuration::get('SMAILY_RSS_SORT_ORDER')),
+ 'smaily_optin_autoresponder' => $optin_autoresponder,
+ 'smaily_optin_enabled' => pSQL(Configuration::get('SMAILY_OPTIN_ENABLED')),
)
);
// Display settings form.
@@ -443,17 +448,72 @@ public function hookDisplayBackOfficeHeader()
}
/**
- * Log API response to text-file.
+ * Trigger Smaily Opt-in if customer joins with newsletter subscription.
*
- * @param string $filename Name of the file created.
- * @param string $msg Text response from api.
- * @return void
+ * @param array $params Array of parameters being passed to the hook function.
+ * @return bool Success of the operation.
*/
- public function logToFile($filename, $response)
+ public function hookActionCustomerAccountAdd($params)
{
- $logger = new FileLogger(1);
- $logger->setFilename(_PS_MODULE_DIR_. $this->name ."/" . $filename);
- $logger->logInfo('Response from API - ' . $response);
+ if (empty($params['newCustomer'])) {
+ return false;
+ }
+ $email = $params['newCustomer']->email;
+ if (!Validate::isEmail($email)) {
+ return false;
+ }
+ $is_newsletter_checked = $params['newCustomer']->newsletter === "1";
+ $is_subscription_optin_enabled = Configuration::get('SMAILY_OPTIN_ENABLED') === "1";
+ if (!$is_newsletter_checked || !$is_subscription_optin_enabled) {
+ return false;
+ }
+
+ $autoresponder = Configuration::get('SMAILY_OPTIN_AUTORESPONDER');
+ $autoresponder_id = empty($autoresponder) ? '' : (int) $autoresponder;
+ $query = array(
+ 'autoresponder' => $autoresponder_id,
+ 'addresses' => [['email' => $email]]
+ );
+ $response = $this->callApi('autoresponder', $query, 'POST');
+ $opt_in_successful = array_key_exists('success', $response) && isset($response['result']['code']) && $response['result']['code'] === 101;
+ if (array_key_exists('success', $response) &&
+ isset($response['result']['code']) &&
+ $response['result']['code'] === 101) {
+ return true; // All good.
+ } else {
+ // Supply query values and save log of unsuccesful operation.
+ $this->logErrorWithFormatting(
+ "Failed to opt-in new customer with email: %s using autoresponder ID: %s. Smaily response code: %s, message: %s.",
+ $query['addresses'][0]['email'],
+ $query['autoresponder'],
+ $response['result']['code'],
+ $response['result']['message']
+ );
+ return false;
+ }
+ }
+
+ /**
+ * Add error (severity 3) to Prestashop log with formatted arguments.
+ *
+ * @param string $message
+ * @return void
+ */
+ public function logErrorWithFormatting() {
+ $args = func_get_args();
+ $message = call_user_func_array('sprintf', $args);
+ PrestaShopLogger::addLog("[SMAILY] " . $message, 3);
+ }
+
+ /**
+ * Add information to Prestashop log.
+ *
+ * @param string $message
+ * @param int $severity (1 is informative, 3 error)
+ * @return void
+ */
+ public function logMessageWithSeverity($message, $severity) {
+ PrestaShopLogger::addLog("[SMAILY] " . $message, $severity);
}
/**
diff --git a/translations/et.php b/translations/et.php
index e0220d33..310e7b61 100644
--- a/translations/et.php
+++ b/translations/et.php
@@ -43,6 +43,10 @@
$_MODULE['<{smailyforprestashop}prestashop>smaily_configure_bb7b3c6261b41de1bd1fefa377a75f43'] = 'Identifikaator on vajalik turvalisuse tagamiseks. Kasuta automaatselt loodud identifikaatorit või asenda enda valitud väärtusega. ';
$_MODULE['<{smailyforprestashop}prestashop>smaily_configure_5588ea18ef47155105d7d11abcb7e4e1'] = 'Croni URL';
$_MODULE['<{smailyforprestashop}prestashop>smaily_configure_9cc2022eb76bc383c713c406b6ae96f2'] = 'Et aktiveerida automaatne kontaktide sünkroniseerimine seadistage Cron oma teenusepakkuja juures.';
+$_MODULE['<{smailyforprestashop}prestashop>smaily_configure_daf2a96781f203ddd0e0c8ba8fa25a2f'] = 'Käivita opt-in kasutaja registreerimisel';
+$_MODULE['<{smailyforprestashop}prestashop>smaily_configure_dc7361b8c5d6e2b9f95b8968533d7b14'] = 'Opt-in käivitatakse ainult siis, kui kasutaja loob konto ja liitub uudiskirjaga. Muutused uudiskirja sätetele adminpaneelis ei käivita opt-in\'i.';
+$_MODULE['<{smailyforprestashop}prestashop>smaily_configure_f31fe73b24620e23d03fd55013e1bf87'] = 'Kasutaja registreerimisel käivitatav automaatika';
+$_MODULE['<{smailyforprestashop}prestashop>smaily_configure_faa5e8094afca015fa4b4a702ed57645'] = 'Käivita iga opt-in automaatika';
$_MODULE['<{smailyforprestashop}prestashop>smaily_configure_c9cc8cce247e49bae79f15173ce97354'] = 'Salvesta';
$_MODULE['<{smailyforprestashop}prestashop>smaily_configure_a27d20b558af715c91592bcee1019dee'] = 'Aktiveeri Unustatud Ostukorvi Meeldetuletus';
$_MODULE['<{smailyforprestashop}prestashop>smaily_configure_872bc575218e7dd2c749633da28c24ab'] = 'Automaatvastaja';
diff --git a/upgrade/Upgrade-1.5.0.php b/upgrade/Upgrade-1.5.0.php
new file mode 100644
index 00000000..5636a98c
--- /dev/null
+++ b/upgrade/Upgrade-1.5.0.php
@@ -0,0 +1,43 @@
+.
+ *
+ * @author Smaily