Skip to content

Commit

Permalink
SearchKit - Add contacts to mailing group in batches
Browse files Browse the repository at this point in the history
For the "Email - schedule/send via CiviMail" action, this switches to
using the batch runner for adding contacts to the mailing group instead of
doing it all at once via chaining.
This prevents timeouts when creating very large mailings > 500 contacts.
  • Loading branch information
colemanw committed Aug 14, 2022
1 parent a832e4c commit ceb5a01
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
if (ctrl.action === 'save') {
// For the save action, take each record from params and copy it with each supplied id
params.records = _.transform(ctrl.ids.slice(ctrl.first, ctrl.last), function(records, id) {
_.each(_.cloneDeep(ctrl.params.records), function(record) {
_.each(_.cloneDeep(ctrl.params.records || [{}]), function(record) {
record[ctrl.idField || 'id'] = id;
records.push(record);
});
Expand Down
18 changes: 10 additions & 8 deletions ext/search_kit/ang/crmSearchTasks/crmSearchTaskMailing.ctrl.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
var ts = $scope.ts = CRM.ts('org.civicrm.search_kit'),
// Combine this controller with model properties (ids, entity, entityInfo) and searchTaskBaseTrait
ctrl = angular.extend(this, $scope.model, searchTaskBaseTrait),
mailingId,
templateTypes;

this.entityTitle = this.getEntityTitle();
Expand All @@ -27,20 +28,13 @@
});

this.submit = function() {
var contacts = _.transform(ctrl.ids, function(records, cid) {
records.push({contact_id: cid});
});
ctrl.start({
values: {
title: 'Hidden Group ' + Date.now(),
is_hidden: true,
'group_type:name': ['Mailing List'],
},
chain: {
contacts: ['GroupContact', 'save', {
defaults: {group_id: '$id'},
records: contacts
}],
mailing: ['Mailing', 'create', {
values: {
name: ctrl.name,
Expand All @@ -59,9 +53,17 @@
});
};

// After running first api call to create group & mailing,
// This runs a batch of api calls to add contacts to the mailing group
this.afterGroupCreate = function(result) {
mailingId = result[0].mailing.id;
ctrl.addContacts = {
defaults: {group_id: result[0].id}
};
};

this.onSuccess = function(result) {
window.location = CRM.url('civicrm/a#/mailing/' + result[0].mailing.id);
window.location = CRM.url('civicrm/a#/mailing/' + mailingId);
};

this.onError = function() {
Expand Down
8 changes: 6 additions & 2 deletions ext/search_kit/ang/crmSearchTasks/crmSearchTaskMailing.html
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,13 @@
{{:: ts('All of the selected contacts have active email addresses.') }}
</div>
</div>
<div ng-if="$ctrl.run" class="crm-search-task-progress">
<div ng-if="$ctrl.run && !$ctrl.addContacts" class="crm-search-task-progress">
<h5>{{:: ts('Creating mailing...') }}</h5>
<crm-search-batch-runner entity="'Group'" action="create" params="$ctrl.run" success="$ctrl.onSuccess(result)" error="$ctrl.onError()" ></crm-search-batch-runner>
<crm-search-batch-runner entity="'Group'" action="create" params="$ctrl.run" success="$ctrl.afterGroupCreate(result)" error="$ctrl.onError()" ></crm-search-batch-runner>
</div>
<div ng-if="$ctrl.addContacts" class="crm-search-task-progress">
<h5>{{:: ts('Adding contacts...') }}</h5>
<crm-search-batch-runner entity="'GroupContact'" action="save" params="$ctrl.addContacts" ids="$ctrl.ids" id-field="contact_id" success="$ctrl.onSuccess(result)" error="$ctrl.onError()" ></crm-search-batch-runner>
</div>
<crm-dialog-button text="ts('Cancel')" icons="{primary: 'fa-times'}" on-click="$ctrl.cancel()" disabled="$ctrl.run" />
<crm-dialog-button text="ts('Create Mailing')" icons="{primary: 'fa-paper-plane'}" on-click="$ctrl.submit()" disabled="!$ctrl.recipientCount || $ctrl.run || !crmSearchTaskMailingForm.$valid" />
Expand Down

0 comments on commit ceb5a01

Please sign in to comment.