Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
CiviCRM: For gift memberships, send email receipt to the giver
CiviCRM: For gift memberships, send email receipt to the giver
The question:
When Alice is creating and paying for a gift membership for Bob, she enters Bob's contact info and email address on the Membership Contribution form, so the emailed receipt goes to Bob (with a copy also going to the back office via the cc settings on the form) and Bob's email address becomes part of the contact record.
We have an optional custom field on the form where Alice can enter her own (different) email address and, ideally, receive a copy of the receipt as well.
in CiviCRM 4.6 we could make this happen by patching into postProcessMembership(), pulling the email address out of the form parameters, and tacking it onto the cc_receipt field that was passed to the sendMail function. However, in 4.7, the form handling is different enough that this method no longer works.
Is there a clean way to add a recipient to the emailed contribution receipt based on a value entered on the contribution form in CiviCRM 4.7?
The answer:
(1) Implement hook_civicrm_postProcess() in a Drupal 7 module, and use it to get the giver email from $form->_submitValues. Stash it into a global variable.
(2) In CRM/Contribute/BAO/Contribution.php, patch function composeMessageArray() to append the giver email to $values['cc_receipt'] prior to the sendMail calls at the end of the function, then clear the global.
Details below.
I couldn't find a way to avoid patching core, but I tried to make the patch as small and unobtrusive as possible. Here's how it was done.
In a separate Drupal 7 module, I implemented hook_civicrm_postProcess(), as follows:
function my_module_civicrm_postProcess($formName, &$form) {
if ($formName == 'CRM_Contribute_Form_Contribution_Confirm' &&
isset($form->_id) && $form->_id == MY_MODULE_CONTRIBUTION_FORM_ID) {
_my_module_civicrm_postProcessMembershipContributionForm($formName, $form);
// ...check for other forms and handle them
function _my_module_civicrm_postProcessMembershipContributionForm($formName, &$form) {
// other post-processing stuff...
// Check for name and email of giver and if it exists, set a global that can
// be used by patched CiviCRM to add to the CC recipients. Used in
// civicrm/CRM/Contribution/BAO/Contribution.php, function composeMessageArray().
if (isset($form->_submitValues[MY_MODULE_GIVER_EMAIL])) {
$giver_mail = $form->_submitValues[MY_MODULE_GIVER_EMAIL];
$giver_name = $form->_submitValues[MY_MODULE_GIVER_NAME];
// Email was validated by form, but we must sanitize the name to avoid
// extra address injection.
$giver_name = mb_encode_mimeheader($giver_name, "UTF-8", "Q");
if (!empty($giver_mail)) {
global $my_module_giver_full_email;
if (!empty($giver_name)) {
$my_module_giver_full_email = '"' . $giver_name . '" <' . $giver_mail . '>';
else {
$my_module_giver_full_email = $giver_mail;
And then this patch to CiviCRM, which needs to be reapplied after every update.
Index: sites/all/modules/civicrm/CRM/Contribute/BAO/Contribution.php
--- sites/all/modules/civicrm/CRM/Contribute/BAO/Contribution.php (revision 3067)
+++ sites/all/modules/civicrm/CRM/Contribute/BAO/Contribution.php (revision 3068)
@@ -2531,6 +2531,16 @@
$template->assign('updateSubscriptionUrl', $url);
+ // If we set this global variable in my_module.module,
+ // append the giver to the CC list.
+ global $my_module_giver_full_email;
+ if (!empty($my_module_giver_full_email)) {
+ if (empty($values['cc_receipt'])) {
+ $values['cc_receipt'] = $my_module_giver_full_email;
+ }
+ else {
+ $values['cc_receipt'] .= ',' . $my_module_giver_full_email;
+ }
+ }
$result = CRM_Contribute_BAO_ContributionPage::sendMail($ids['contact'], $values, $isTest, $returnMessageText);
return $result;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.