1 (function (angular
, $, _
) {
2 var partialUrl = function (relPath
) {
3 return CRM
.resourceUrls
['civicrm'] + '/partials/crmMailing2/' + relPath
;
6 var crmMailing2
= angular
.module('crmMailing2');
8 // The representation of from/reply-to addresses is inconsistent in the mailing data-model,
9 // so the UI must do some adaptation. The crmFromAddresses provides a richer way to slice/dice
10 // the available "From:" addrs. Records are like the underlying OptionValues -- but add "email"
12 crmMailing2
.factory('crmFromAddresses', function($q
, crmApi
) {
13 var emailRegex
= /^"(.*)" \<([^@\>]*@[^@\>]*)\>$/;
14 var addrs
= _
.map(CRM
.crmMailing
.fromAddress
, function(addr
){
15 var match
= emailRegex
.exec(addr
.label
);
16 return _
.extend({}, addr
, {
17 email
: match
? match
[2] : '(INVALID)',
18 author
: match
? match
[1] : '(INVALID)'
21 function first(array
) {
22 return (array
.length
== 0) ? null : array
[0];
26 getAll
: function getAll() {
29 getByAuthorEmail
: function getByAuthorEmail(author
, email
, autocreate
) {
31 _
.each(addrs
, function(addr
){
32 if (addr
.author
== author
&& addr
.email
== email
) {
36 if (!result
&& autocreate
) {
38 label
: '(INVALID) "' + author
+ '" <' + email
+ '>',
46 getByEmail
: function getByEmail(email
) {
47 return first(_
.where(addrs
, {email
: email
}));
49 getByLabel: function(label
) {
50 return first(_
.where(addrs
, {label
: label
}));
52 getDefault
: function getDefault() {
53 return first(_
.where(addrs
, {is_default
: "1"}));
58 // The crmMailingMgr service provides business logic for loading, saving, previewing, etc
59 crmMailing2
.factory('crmMailingMgr', function($q
, crmApi
, crmFromAddresses
) {
60 window
.f
= crmFromAddresses
; // REVERT
61 var pickDefaultMailComponent
= function pickDefaultMailComponent(type
) {
62 var mcs
= _
.where(CRM
.crmMailing
.headerfooterList
, {
66 return (mcs
.length
>= 1) ? mcs
[0].id
: null;
70 // @param scalar idExpr a number or the literal string 'new'
71 // @return Promise|Object Mailing (per APIv3)
72 getOrCreate
: function getOrCreate(idExpr
) {
73 return (idExpr
== 'new') ? this.create() : this.get(idExpr
);
75 // @return Promise Mailing (per APIv3)
76 get: function get(id
) {
77 return crmApi('Mailing', 'getsingle', {id
: id
}).then(function(mailing
){
78 return crmApi('MailingGroup', 'get', {mailing_id
: id
}).then(function(groupResult
){
79 mailing
.groups
= {include
: [], exclude
: []};
80 mailing
.mailings
= {include
: [], exclude
: []};
81 _
.each(groupResult
.values
, function(mailingGroup
) {
82 var bucket
= (mailingGroup
.entity_table
== 'civicrm_group') ? 'groups' : 'mailings';
83 var entityId
= parseInt(mailingGroup
.entity_id
);
84 mailing
[bucket
][mailingGroup
.group_type
].push(entityId
);
90 // @return Object Mailing (per APIv3)
91 create
: function create() {
93 name
: "revert this", // fixme
95 from_name
: crmFromAddresses
.getDefault().author
,
96 from_email
: crmFromAddresses
.getDefault().email
,
98 subject
: "For {contact.display_name}", // fixme
100 groups
: {include
: [2], exclude
: [4]}, // fixme
101 mailings
: {include
: [], exclude
: []},
102 body_html
: "<b>Hello</b> {contact.display_name}", // fixme
103 body_text
: "Hello {contact.display_name}", // fixme
104 footer_id
: null, // pickDefaultMailComponent('Footer'),
105 header_id
: null, // pickDefaultMailComponent('Header'),
106 visibility
: "Public Pages",
109 forward_replies
: "0",
113 optout_id
: pickDefaultMailComponent('OptOut'),
114 reply_id
: pickDefaultMailComponent('Reply'),
115 resubscribe_id
: pickDefaultMailComponent('Resubscribe'),
116 unsubscribe_id
: pickDefaultMailComponent('Unsubscribe')
120 // @param mailing Object (per APIv3)
122 'delete': function(mailing
) {
124 return crmApi('Mailing', 'delete', {id
: mailing
.id
});
132 // @param mailing Object (per APIv3)
133 // @return Promise an object with "subject", "body_text", "body_html"
134 preview
: function preview(mailing
) {
135 var params
= _
.extend({}, mailing
, {
136 options
: {force_rollback
: 1},
137 'api.Mailing.preview': {
141 return crmApi('Mailing', 'create', params
).then(function(result
){
142 // changes rolled back, so we don't care about updating mailing
143 return result
.values
[result
.id
]['api.Mailing.preview'].values
;
147 // @param mailing Object (per APIv3)
148 // @param int previewLimit
149 // @return Promise for a list of recipients (mailing_id, contact_id, api.contact.getvalue, api.email.getvalue)
150 previewRecipients
: function previewRecipients(mailing
, previewLimit
) {
151 // To get list of recipients, we tentatively save the mailing and
152 // get the resulting recipients -- then rollback any changes.
153 var params
= _
.extend({}, mailing
, {
154 options
: {force_rollback
: 1},
155 'api.mailing_job.create': 1, // note: exact match to API default
156 'api.MailingRecipients.get': {
157 mailing_id
: '$value.id',
158 options
: { limit
: previewLimit
},
159 'api.contact.getvalue': {'return': 'display_name'},
160 'api.email.getvalue': {'return': 'email'}
163 return crmApi('Mailing', 'create', params
).then(function(recipResult
){
164 // changes rolled back, so we don't care about updating mailing
165 return recipResult
.values
[recipResult
.id
]['api.MailingRecipients.get'].values
;
169 // @param mailing Object (per APIv3)
171 save: function(mailing
) {
172 var params
= _
.extend({}, mailing
, {
173 'api.mailing_job.create': 0 // note: exact match to API default
175 return crmApi('Mailing', 'create', params
).then(function(result
){
176 if (result
.id
&& !mailing
.id
) mailing
.id
= result
.id
; // no rollback, so update mailing.id
177 return result
.values
[result
.id
];
181 // Schedule/send the mailing
182 // @param mailing Object (per APIv3)
184 submit: function(mailing
) {
185 throw 'Not implemented: crmMailingMgr.submit';
186 // var params = _.extend({}, mailing, {
187 // 'api.mailing_job.create': 1 // note: exact match to API default
189 // return crmApi('Mailing', 'create', params).then(function(result){
190 // if (result.id && !mailing.id) mailing.id = result.id; // no rollback, so update mailing.id
191 // return result.values[result.id];
195 // Immediately send a test message
196 // @param mailing Object (per APIv3)
197 // @param testEmail string
198 // @param testGroup int (id#)
199 // @return Promise for a list of delivery reports
200 sendTest: function(mailing
, testEmail
, testGroup
) {
201 var params
= _
.extend({}, mailing
, {
202 // options: {force_rollback: 1},
203 'api.Mailing.send_test': {
204 mailing_id
: '$value.id',
205 test_email
: testEmail
,
206 test_group
: testGroup
209 return crmApi('Mailing', 'create', params
).then(function(result
){
210 if (result
.id
&& !mailing
.id
) mailing
.id
= result
.id
; // no rollback, so update mailing.id
211 return result
.values
[result
.id
]['api.Mailing.send_test'].values
;
217 })(angular
, CRM
.$, CRM
._
);