diff --git a/lib/models/campaigns.js b/lib/models/campaigns.js index 1291cd78..4f8aa610 100644 --- a/lib/models/campaigns.js +++ b/lib/models/campaigns.js @@ -16,7 +16,7 @@ let _ = require('../translate')._; let util = require('util'); let tableHelpers = require('../table-helpers'); -let allowedKeys = ['description', 'from', 'address', 'reply_to', 'subject', 'editor_name', 'editor_data', 'template', 'source_url', 'list', 'segment', 'html', 'text', 'tracking_disabled']; +let allowedKeys = ['description', 'from', 'address', 'reply_to', 'subject', 'editor_name', 'editor_data', 'template', 'source_url', 'list', 'segment', 'html', 'text', 'click_tracking_disabled', 'open_tracking_disabled']; module.exports.list = (start, limit, callback) => { tableHelpers.list('campaigns', ['*'], 'scheduled', null, start, limit, callback); @@ -370,7 +370,8 @@ module.exports.create = (campaign, opts, callback) => { campaign = tools.convertKeys(campaign); let name = (campaign.name || '').toString().trim(); - campaign.trackingDisabled = campaign.trackingDisabled ? 1 : 0; + campaign.openTrackingDisabled = campaign.openTrackingDisabled ? 1 : 0; + campaign.clickTrackingDisabled = campaign.clickTrackingDisabled ? 1 : 0; opts = opts || {}; @@ -592,7 +593,8 @@ module.exports.update = (id, updates, callback) => { let campaign = tools.convertKeys(updates); let name = (campaign.name || '').toString().trim(); - campaign.trackingDisabled = campaign.trackingDisabled ? 1 : 0; + campaign.openTrackingDisabled = campaign.openTrackingDisabled ? 1 : 0; + campaign.clickTrackingDisabled = campaign.clickTrackingDisabled ? 1 : 0; if (!name) { return callback(new Error(_('Campaign Name must be set'))); diff --git a/lib/models/links.js b/lib/models/links.js index ed348ad3..e7ce5591 100644 --- a/lib/models/links.js +++ b/lib/models/links.js @@ -42,7 +42,7 @@ module.exports.countClick = (remoteIp, useragent, campaignCid, listCid, subscrip return callback(err); } - if (!data || data.campaign.trackingDisabled) { + if (!data || data.campaign.clickTrackingDisabled) { return callback(null, false); } @@ -158,7 +158,7 @@ module.exports.countOpen = (remoteIp, useragent, campaignCid, listCid, subscript return callback(err); } - if (!data || data.campaign.trackingDisabled) { + if (!data || data.campaign.openTrackingDisabled) { return callback(null, false); } @@ -268,56 +268,64 @@ module.exports.add = (url, campaignId, callback) => { }; module.exports.updateLinks = (campaign, list, subscription, serviceUrl, message, callback) => { - if (campaign.trackingDisabled || !message || !message.trim()) { + if ((campaign.openTrackingDisabled && campaign.clickTrackingDisabled) || !message || !message.trim()) { // tracking is disabled, do not modify the message return setImmediate(() => callback(null, message)); } - let re = /(]* href\s*=[\s"']*)(http[^"'>\s]+)/gi; - let urls = new Set(); - (message || '').replace(re, (match, prefix, url) => { - urls.add(url); - }); - - let map = new Map(); - let vals = urls.values(); - + // insert tracking image - let inserted = false; - let imgUrl = urllib.resolve(serviceUrl, util.format('/links/%s/%s/%s', campaign.cid, list.cid, encodeURIComponent(subscription.cid))); - let img = 'mt'; - message = message.replace(/<\/body\b/i, match => { - inserted = true; - return img + match; - }); - if (!inserted) { - message = message + img; - } - - let replaceUrls = () => { - callback(null, - message.replace(re, (match, prefix, url) => - prefix + (map.has(url) ? urllib.resolve(serviceUrl, util.format('/links/%s/%s/%s/%s', campaign.cid, list.cid, encodeURIComponent(subscription.cid), encodeURIComponent(map.get(url)))) : url))); - }; - - let storeNext = () => { - let urlItem = vals.next(); - if (urlItem.done) { - return replaceUrls(); - } - - module.exports.add(he.decode(urlItem.value, { - isAttributeValue: true - }), campaign.id, (err, linkId, cid) => { - if (err) { - log.error('Link', err); - return storeNext(); - } - map.set(urlItem.value, cid); - return storeNext(); + if (!campaign.openTrackingDisabled) { + let inserted = false; + let imgUrl = urllib.resolve(serviceUrl, util.format('/links/%s/%s/%s', campaign.cid, list.cid, encodeURIComponent(subscription.cid))); + let img = 'mt'; + message = message.replace(/<\/body\b/i, match => { + inserted = true; + return img + match; + }); + if (!inserted) { + message = message + img; + } + if (campaign.clickTrackingDisabled) { + return callback(null, message); + } + } + + if (!campaign.clickTrackingDisabled) { + let re = /(]* href\s*=[\s"']*)(http[^"'>\s]+)/gi; + let urls = new Set(); + (message || '').replace(re, (match, prefix, url) => { + urls.add(url); }); - }; - storeNext(); + let map = new Map(); + let vals = urls.values(); + + let replaceUrls = () => { + callback(null, + message.replace(re, (match, prefix, url) => + prefix + (map.has(url) ? urllib.resolve(serviceUrl, util.format('/links/%s/%s/%s/%s', campaign.cid, list.cid, encodeURIComponent(subscription.cid), encodeURIComponent(map.get(url)))) : url))); + }; + + let storeNext = () => { + let urlItem = vals.next(); + if (urlItem.done) { + return replaceUrls(); + } + + module.exports.add(he.decode(urlItem.value, { + isAttributeValue: true + }), campaign.id, (err, linkId, cid) => { + if (err) { + log.error('Link', err); + return storeNext(); + } + map.set(urlItem.value, cid); + return storeNext(); + }); + }; + + storeNext(); + } }; function getSubscriptionData(campaignCid, listCid, subscriptionCid, callback) { diff --git a/meta.json b/meta.json index 22fe97fb..aa851e29 100644 --- a/meta.json +++ b/meta.json @@ -1,3 +1,3 @@ { - "schemaVersion": 27 + "schemaVersion": 28 } diff --git a/setup/sql/mailtrain-test.sql b/setup/sql/mailtrain-test.sql index 8ae97db9..6533f3a4 100644 --- a/setup/sql/mailtrain-test.sql +++ b/setup/sql/mailtrain-test.sql @@ -69,7 +69,8 @@ CREATE TABLE `campaigns` ( `html_prepared` longtext, `text` longtext, `status` tinyint(4) unsigned NOT NULL DEFAULT '1', - `tracking_disabled` tinyint(4) unsigned NOT NULL DEFAULT '0', + `open_tracking_disabled` tinyint(4) unsigned NOT NULL DEFAULT '0', + `click_tracking_disabled` tinyint(4) unsigned NOT NULL DEFAULT '0', `scheduled` timestamp NULL DEFAULT NULL, `status_change` timestamp NULL DEFAULT NULL, `delivered` int(11) unsigned NOT NULL DEFAULT '0', diff --git a/setup/sql/mailtrain.sql b/setup/sql/mailtrain.sql index d56c9806..02817a37 100644 --- a/setup/sql/mailtrain.sql +++ b/setup/sql/mailtrain.sql @@ -65,7 +65,8 @@ CREATE TABLE `campaigns` ( `html_prepared` longtext, `text` longtext, `status` tinyint(4) unsigned NOT NULL DEFAULT '1', - `tracking_disabled` tinyint(4) unsigned NOT NULL DEFAULT '0', + `click_tracking_disabled` tinyint(4) unsigned NOT NULL DEFAULT '0', + `open_tracking_disabled` tinyint(4) unsigned NOT NULL DEFAULT '0', `scheduled` timestamp NULL DEFAULT NULL, `status_change` timestamp NULL DEFAULT NULL, `delivered` int(11) unsigned NOT NULL DEFAULT '0', diff --git a/setup/sql/upgrade-00028.sql b/setup/sql/upgrade-00028.sql new file mode 100644 index 00000000..47212891 --- /dev/null +++ b/setup/sql/upgrade-00028.sql @@ -0,0 +1,13 @@ +# Header section +# Define incrementing schema version number +SET @schema_version = '28'; + +# Rename column tracking_disabled +ALTER TABLE `campaigns` ADD COLUMN `open_tracking_disabled` tinyint(4) unsigned DEFAULT 0 NOT NULL, ADD COLUMN `click_tracking_disabled` tinyint(4) unsigned DEFAULT 0 NOT NULL; +UPDATE `campaigns` SET `open_tracking_disabled` = `tracking_disabled`, `click_tracking_disabled` = `tracking_disabled`; +ALTER TABLE `campaigns` DROP COLUMN `tracking_disabled`; + +# Footer section +LOCK TABLES `settings` WRITE; +INSERT INTO `settings` (`key`, `value`) VALUES('db_schema_version', @schema_version) ON DUPLICATE KEY UPDATE `value`=@schema_version; +UNLOCK TABLES; diff --git a/views/campaigns/create-rss.hbs b/views/campaigns/create-rss.hbs index 131a4a5d..709c1df9 100644 --- a/views/campaigns/create-rss.hbs +++ b/views/campaigns/create-rss.hbs @@ -84,7 +84,15 @@
+
+
+ +
+
+
diff --git a/views/campaigns/create-triggered.hbs b/views/campaigns/create-triggered.hbs index 8fdafbe5..f2711dc7 100644 --- a/views/campaigns/create-triggered.hbs +++ b/views/campaigns/create-triggered.hbs @@ -104,7 +104,15 @@
+
+
+ +
+
+
diff --git a/views/campaigns/create.hbs b/views/campaigns/create.hbs index b5869898..24c74fc1 100644 --- a/views/campaigns/create.hbs +++ b/views/campaigns/create.hbs @@ -110,7 +110,15 @@
+
+
+ +
+
+
diff --git a/views/campaigns/edit-rss.hbs b/views/campaigns/edit-rss.hbs index 3c13c859..967094bd 100644 --- a/views/campaigns/edit-rss.hbs +++ b/views/campaigns/edit-rss.hbs @@ -111,7 +111,15 @@
+
+
+ +
+
+
diff --git a/views/campaigns/edit-triggered.hbs b/views/campaigns/edit-triggered.hbs index cdefe5fc..b94c2b0d 100644 --- a/views/campaigns/edit-triggered.hbs +++ b/views/campaigns/edit-triggered.hbs @@ -103,7 +103,15 @@
+
+
+ +
+
+
diff --git a/views/campaigns/edit.hbs b/views/campaigns/edit.hbs index 098b502a..faa0053c 100644 --- a/views/campaigns/edit.hbs +++ b/views/campaigns/edit.hbs @@ -121,7 +121,15 @@
+
+
+ +
+
+
diff --git a/views/campaigns/view.hbs b/views/campaigns/view.hbs index a8e981b3..dcf278b1 100644 --- a/views/campaigns/view.hbs +++ b/views/campaigns/view.hbs @@ -164,7 +164,7 @@ - {{#unless trackingDisabled}} + {{#unless openTrackingDisabled}}
{{#translate}}Opened{{/translate}}
@@ -174,7 +174,8 @@
- + {{/unless}} + {{#unless clickTrackingDisabled}}
{{#translate}}Clicked{{/translate}}