From: Tim Otten Date: Fri, 12 Dec 2014 00:26:01 +0000 (-0800) Subject: CRM-15578 - Add crmMailingAB2 module (based on crmMailingAB). Add skeletal list/edit... X-Git-Url: https://vcs.fsf.org/?a=commitdiff_plain;h=70980d8e3999cc7ffe2973a027c5aa4d320f728a;p=civicrm-core.git CRM-15578 - Add crmMailingAB2 module (based on crmMailingAB). Add skeletal list/edit screens. --- diff --git a/CRM/Mailing/Info.php b/CRM/Mailing/Info.php index 758c092bdb..5c5b3ed1cc 100644 --- a/CRM/Mailing/Info.php +++ b/CRM/Mailing/Info.php @@ -70,6 +70,11 @@ class CRM_Mailing_Info extends CRM_Core_Component_Info { 'js' => array('js/angular-crmMailing2.js', 'js/angular-crmMailing2-services.js', 'js/angular-crmMailing2-directives.js'), 'css' => array('css/angular-crmMailing2.css'), ); + $result['crmMailingAB2'] = array( + 'ext' => 'civicrm', + 'js' => array('js/angular-crmMailingAB2.js', 'js/angular-crmMailingAB2-services.js'), + 'css' => array('css/angular-crmMailingAB2.css'), + ); $result['crmMailingAB'] = array( 'ext' => 'civicrm', 'js' => array( diff --git a/css/angular-crmMailingAB2.css b/css/angular-crmMailingAB2.css new file mode 100644 index 0000000000..e69de29bb2 diff --git a/js/angular-crmMailing2-services.js b/js/angular-crmMailing2-services.js index b02b6539f0..340608a38a 100644 --- a/js/angular-crmMailing2-services.js +++ b/js/angular-crmMailing2-services.js @@ -197,6 +197,7 @@ // ex: crmMailingMgr.mergeInto(newMailing, mailingTemplate, ['subject']); mergeInto: function mergeInto(mailingTgt, mailingFrom, excludes) { var MAILING_FIELDS = [ + // always exclude: 'id' 'name', 'campaign_id', 'from_name', diff --git a/js/angular-crmMailingAB2-services.js b/js/angular-crmMailingAB2-services.js new file mode 100644 index 0000000000..b077d50931 --- /dev/null +++ b/js/angular-crmMailingAB2-services.js @@ -0,0 +1,122 @@ +(function (angular, $, _) { + + angular.module('crmMailingAB2').factory('crmMailingABCriteria', function () { + // TODO Get data from server + var values = { + '1': {value: '1', name: 'Subject lines', label: ts('Different "Subject" lines')}, + '2': {value: '2', name: 'From names', label: ts('Different "From" names')}, + '3': {value: '3', name: 'Two different emails', label: ts('Entirely different emails')} + }; + return { + get: function get(value) { + var r = _.where(values, {value: '' + value}); + return r.length > 0 ? r[0] : null; + }, + getAll: function getAll() { + return values; + } + }; + }); + + // CrmMailingAB is a data-model which combines an AB test (APIv3 "MailingAB") and three mailings (APIv3 "Mailing"). + angular.module('crmMailingAB2').factory('CrmMailingAB', function (crmApi, crmMailingMgr, $q) { + function CrmMailingAB(id) { + this.id = id; + this.mailings = {}; + } + + angular.extend(CrmMailingAB.prototype, { + // @return Promise CrmMailingAB + load: function load() { + var crmMailingAB = this; + if (!crmMailingAB.id) { + crmMailingAB.ab = { + name: '', + mailing_id_a: null, + mailing_id_b: null, + mailing_id_c: null, + domain_id: null, + testing_criteria_id: null, + winner_criteria_id: null, + specific_url: '', + declare_winning_time: null, + group_percentage: 10 + }; + crmMailingAB.mailings.a = crmMailingMgr.create(); + crmMailingAB.mailings.b = crmMailingMgr.create(); + crmMailingAB.mailings.c = crmMailingMgr.create(); + + var dfr = $q.defer(); + dfr.resolve(crmMailingAB); + return dfr.promise; + } + else { + return crmApi('MailingAB', 'get', {id: crmMailingAB.id}) + .then(function (abResult) { + crmMailingAB.ab = abResult.values[abResult.id]; + return crmMailingAB._loadMailings(); + }); + } + }, + // @return Promise CrmMailingAB + save: function save() { + var crmMailingAB = this; + + return crmMailingAB._saveMailings() + .then(function () { + return crmApi('MailingAB', 'create', crmMailingAB.ab) + .then(function (abResult) { + crmMailingAB.ab.id = abResult.id; + }); + }) + .then(function () { + return crmMailingAB; + }); + }, + // Load mailings A, B, and C (if available) + // @return Promise CrmMailingAB + _loadMailings: function _loadMailings() { + var crmMailingAB = this; + var todos = {}; + _.each(['a', 'b', 'c'], function (mkey) { + if (crmMailingAB.ab['mailing_id_' + mkey]) { + todos[mkey] = crmMailingMgr.get(crmMailingAB.ab['mailing_id_' + mkey]) + .then(function (mailing) { + crmMailingAB.mailings[mkey] = mailing; + }); + } + else { + crmMailingAB.mailings[mkey] = crmMailingMgr.create(); + } + }); + return $q.all(todos).then(function () { + return crmMailingAB; + }); + }, + // Save mailings A, B, and C (if available) + // @return Promise CrmMailingAB + _saveMailings: function _saveMailings() { + var crmMailingAB = this; + var todos = {}; + _.each(['a', 'b', 'c'], function (mkey) { + if (!crmMailingAB.mailings[mkey]) { + return; + } + if (crmMailingAB.ab['mailing_id_' + mkey]) { + // paranoia: in case caller forgot to manage id on mailing + crmMailingAB.mailings[mkey].id = crmMailingAB.ab['mailing_id_' + mkey]; + } + todos[mkey] = crmMailingMgr.save(crmMailingAB.mailings[mkey]).then(function(){ + crmMailingAB.ab['mailing_id_' + mkey] = crmMailingAB.mailings[mkey].id; + }); + }); + return $q.all(todos).then(function () { + return crmMailingAB; + }); + } + + }); + return CrmMailingAB; + }); + +})(angular, CRM.$, CRM._); diff --git a/js/angular-crmMailingAB2.js b/js/angular-crmMailingAB2.js new file mode 100644 index 0000000000..0bd3f7b545 --- /dev/null +++ b/js/angular-crmMailingAB2.js @@ -0,0 +1,86 @@ +(function (angular, $, _) { + + var partialUrl = function (relPath, module) { + if (!module) { + module = 'crmMailingAB2'; + } + return CRM.resourceUrls['civicrm'] + '/partials/' + module + '/' + relPath; + }; + + angular.module('crmMailingAB2', ['ngRoute', 'ui.utils', 'ngSanitize', 'crmUi', 'crmMailing2']); + angular.module('crmMailingAB2').config([ + '$routeProvider', + function ($routeProvider) { + $routeProvider.when('/abtest2', { + templateUrl: partialUrl('list.html'), + controller: 'CrmMailingAB2ListCtrl', + resolve: { + mailingABList: function ($route, crmApi) { + return crmApi('MailingAB', 'get', {rowCount: 0}); + } + } + }); + $routeProvider.when('/abtest2/:id', { + templateUrl: partialUrl('edit.html'), + controller: 'CrmMailingAB2EditCtrl', + resolve: { + abtest: function ($route, CrmMailingAB) { + var abtest = new CrmMailingAB($route.current.params.id == 'new' ? null : $route.current.params.id); + return abtest.load(); + } + } + }); + } + ]); + + angular.module('crmMailingAB2').controller('CrmMailingAB2ListCtrl', function ($scope, mailingABList, crmMailingABCriteria) { + $scope.mailingABList = mailingABList.values; + $scope.testing_criteria = crmMailingABCriteria.getAll(); + }) + + + angular.module('crmMailingAB2').controller('CrmMailingAB2EditCtrl', function ($scope, abtest, crmMailingABCriteria, crmMailingMgr) { + $scope.abtest = abtest; + $scope.ts = CRM.ts('CiviMail'); + $scope.sync = function sync() { + abtest.mailings.a.name = ts('Test A (%1)', {1: abtest.ab.name}); + abtest.mailings.b.name = ts('Test B (%1)', {1: abtest.ab.name}); + abtest.mailings.c.name = ts('Winner (%1)', {1: abtest.ab.name}); + + var criteria = crmMailingABCriteria.get(abtest.ab.testing_criteria_id); + if (criteria) { + switch (criteria.name) { + case 'Subject lines': + crmMailingMgr.mergeInto(abtest.mailings.b, abtest.mailings.a, ['name', 'subject']); + break; + case 'From names': + crmMailingMgr.mergeInto(abtest.mailings.b, abtest.mailings.a, ['name', 'from_name', 'from_email']); + break; + case 'Two different emails': + crmMailingMgr.mergeInto(abtest.mailings.b, abtest.mailings.a, [ + 'name', + 'subject', + 'from_name', + 'from_email', + 'body_html', + 'body_text' + ]); + break; + default: + throw "Unrecognized testing_criteria"; + } + } + crmMailingMgr.mergeInto(abtest.mailings.c, abtest.mailings.a, ['name']); + }; + $scope.save = function save() { + $scope.sync(); + return abtest.save(); + }; + $scope.delete = function () { + throw "Not implemented: EditCtrl.delete" + }; + + $scope.sync(); + }); + +})(angular, CRM.$, CRM._); diff --git a/partials/crmMailingAB2/edit.html b/partials/crmMailingAB2/edit.html new file mode 100644 index 0000000000..42b3d14ffe --- /dev/null +++ b/partials/crmMailingAB2/edit.html @@ -0,0 +1,26 @@ +
+
{{abtest|json}}
+
+ +
+
+
+ Name: +
+
+
+ Subject A: +
+
+ Subject B: +
+
+ + + + +
+
diff --git a/partials/crmMailingAB2/list.html b/partials/crmMailingAB2/list.html new file mode 100644 index 0000000000..6556c52440 --- /dev/null +++ b/partials/crmMailingAB2/list.html @@ -0,0 +1,43 @@ + +
+ A/B Testing list +
+ +
+ + + + + + + + + + + + + + + + + + +
TitleIdTest Type
{{mailingAB.name}}{{mailingAB.id}}{{testing_criteria[mailingAB.testing_criteria_id].label}} + Edit  + Results +
+
+ +
+
+ You have no A/B mailings +
+ + +
+
+
New A/B Test
+