diff --git a/CRM/Twingle/Form/Profile.php b/CRM/Twingle/Form/Profile.php index ea83455..a38dc7e 100644 --- a/CRM/Twingle/Form/Profile.php +++ b/CRM/Twingle/Form/Profile.php @@ -357,12 +357,27 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { $this->add( 'select', // field type 'campaign', // field name - E::ts('Campaign (e.g. for donation)'), // field label + E::ts('Default Campaign'), // field label array('' => E::ts('- none -')) + static::getCampaigns(), // list of options FALSE, // is not required array('class' => 'crm-select2 huge') ); + $this->add( + 'select', + 'campaign_targets', + E::ts('Set Campaign for'), + [ + 'contribution' => E::ts("Contribution"), + 'recurring' => E::ts("Recurring Contribution"), + 'membership' => E::ts("Membership"), + 'mandate' => E::ts("SEPA Mandate"), + 'contact' => E::ts("Contacts (XCM)"), + ], + FALSE, // is not required + ['class' => 'crm-select2 huge', 'multiple' => 'multiple'] + ); + $this->add( 'select', // field type 'membership_type_id', // field name @@ -511,9 +526,14 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { $defaults = parent::setDefaultValues(); if (in_array($this->_op, array('create', 'edit'))) { $defaults['name'] = $this->profile->getName(); - foreach ($this->profile->getData() as $element_name => $value) { + $profile_data = $this->profile->getData(); + foreach ($profile_data as $element_name => $value) { $defaults[$element_name] = $value; } + // backwards compatibility, see issue #27 + if (!isset($profile_data['campaign_targets'])) { + $defaults['campaign_targets'] = ['contribution', 'contact']; + } } return $defaults; } diff --git a/CRM/Twingle/Profile.php b/CRM/Twingle/Profile.php index e61f4df..be93bc6 100644 --- a/CRM/Twingle/Profile.php +++ b/CRM/Twingle/Profile.php @@ -215,6 +215,7 @@ class CRM_Twingle_Profile { 'postinfo_groups', 'donation_receipt_groups', 'campaign', + 'campaign_targets', 'contribution_source', 'custom_field_mapping', 'membership_type_id', @@ -287,6 +288,7 @@ class CRM_Twingle_Profile { 'postinfo_groups' => NULL, 'donation_receipt_groups' => NULL, 'campaign' => NULL, + 'campaign_targets' => ['contribution', 'contact'], 'contribution_source' => NULL, 'custom_field_mapping' => NULL, 'membership_type_id' => NULL, diff --git a/CRM/Twingle/Submission.php b/CRM/Twingle/Submission.php index ddd239e..0daee20 100644 --- a/CRM/Twingle/Submission.php +++ b/CRM/Twingle/Submission.php @@ -129,6 +129,8 @@ class CRM_Twingle_Submission { * Data to use for contact lookup/to create a contact with. * @param CRM_Twingle_Profile $profile * Profile used for this process + * @param array $submission + * Submission data * * @return int | NULL * The ID of the matching/created contact, or NULL if no matching contact @@ -136,7 +138,7 @@ class CRM_Twingle_Submission { * @throws \CiviCRM_API3_Exception * When invalid data was given. */ - public static function getContact($contact_type, $contact_data, $profile) { + public static function getContact($contact_type, $contact_data, $profile, $submission = []) { // If no parameters are given, do nothing. if (empty($contact_data)) { return NULL; @@ -148,11 +150,8 @@ class CRM_Twingle_Submission { $contact_data['xcm_profile'] = $xcm_profile; } - // add campaign - $campaign_id = (int) $profile->getAttribute('campaign'); - if ($campaign_id) { - $contact_data['campaign_id'] = $campaign_id; - } + // add campaign, see issue #17 + CRM_Twingle_Submission::setCampaign($contact_data, 'contact', $submission, $profile); // Prepare values: country. if (!empty($contact_data['country'])) { @@ -354,4 +353,39 @@ class CRM_Twingle_Submission { return date('j', $earliest_cycle_day); } + /** + * Will set the campaign_id to the entity_data set, if the + * profile is configured to do so. In that case the campaign is taken + * from the submission data. Should that be empty, the profile's default + * campaign is used. + * + * @param array $entity_data + * the data set where the campaign_id should be set + * @param string $context + * defines the type of the entity_data: one of 'contribution', 'membership','mandate', 'recurring', 'contact' + * @param array $submission + * the submitted data + * @param CRM_Twingle_Profile $profile + * the twingle profile used + */ + public static function setCampaign(&$entity_data, $context, $submission, $profile) { + // first: make sure it's not set from other workflows + unset($entity_data['campaign_id']); + + // then: check if campaign should be set it this context + $enabled_contexts = $profile->getAttribute('campaign_targets'); + if ($enabled_contexts === null || !is_array($enabled_contexts)) { + // backward compatibility: + $enabled_contexts = ['contribution', 'contact']; + } + if (in_array($context, $enabled_contexts)) { + // use the submitted campaign if set + if (!empty($submission['campaign_id'])) { + $entity_data['campaign_id'] = $submission['campaign_id']; + } // otherwise use the profile's + elseif (!empty($campaign = $profile->getAttribute('campaign'))) { + $entity_data['campaign_id'] = $campaign; + } + } + } } diff --git a/CRM/Twingle/Tools.php b/CRM/Twingle/Tools.php index bb3bbb5..86cd828 100644 --- a/CRM/Twingle/Tools.php +++ b/CRM/Twingle/Tools.php @@ -137,12 +137,12 @@ class CRM_Twingle_Tools { 'source_contact_id' => CRM_Core_Session::getLoggedInContactID(), ]); } catch (Exception $ex) { - Civi::log()->debug("TwingleAPI: Couldn't create recurring protection activity: " . $ex->getMessage()); + Civi::log()->warning("TwingleAPI: Couldn't create recurring protection activity: " . $ex->getMessage()); } break; default: - Civi::log()->debug("TwingleAPI: Unknown recurring contribution protection mode: '{$protection_mode}'"); + Civi::log()->warning("TwingleAPI: Unknown recurring contribution protection mode: '{$protection_mode}'"); break; } } @@ -203,7 +203,7 @@ class CRM_Twingle_Tools { return reset($ooff_mandate['values']); } } catch (Exception $ex) { - Civi::log()->debug("CRM_Twingle_Tools::getMandate failed for [{$contribution_id}]: " . $ex->getMessage()); + Civi::log()->warning("CRM_Twingle_Tools::getMandate failed for [{$contribution_id}]: " . $ex->getMessage()); } } return NULL; diff --git a/api/v3/TwingleDonation/Submit.php b/api/v3/TwingleDonation/Submit.php index b15d0b4..f84d21c 100644 --- a/api/v3/TwingleDonation/Submit.php +++ b/api/v3/TwingleDonation/Submit.php @@ -403,7 +403,8 @@ function civicrm_api3_twingle_donation_Submit($params) { if (!$contact_id = CRM_Twingle_Submission::getContact( 'Individual', $contact_data, - $profile + $profile, + $params )) { throw new CiviCRM_API3_Exception( E::ts('Individual contact could not be found or created.'), @@ -439,7 +440,8 @@ function civicrm_api3_twingle_donation_Submit($params) { if (!$organisation_id = CRM_Twingle_Submission::getContact( 'Organization', $organisation_data, - $profile + $profile, + $params )) { throw new CiviCRM_API3_Exception( E::ts('Organisation contact could not be found or created.'), @@ -466,7 +468,9 @@ function civicrm_api3_twingle_donation_Submit($params) { CRM_Twingle_Submission::getContact( 'Individual', array('id' => $contact_id) + $submitted_address, - $profile); + $profile, + $params + ); } // Create employer relationship between organization and individual. @@ -537,12 +541,8 @@ function civicrm_api3_twingle_donation_Submit($params) { $contribution_data['note'] = $params['purpose']; } - if (!empty($params['campaign_id'])) { - $contribution_data['campaign_id'] = $params['campaign_id']; - } - elseif (!empty($campaign = $profile->getAttribute('campaign'))) { - $contribution_data['campaign_id'] = $campaign; - } + // set campaign, subject to configuration + CRM_Twingle_Submission::setCampaign($contribution_data, 'contribution', $params, $profile); if (!empty($contribution_source = $profile->getAttribute('contribution_source'))) { $contribution_data['source'] = $contribution_source; @@ -590,6 +590,9 @@ function civicrm_api3_twingle_donation_Submit($params) { if (!empty($custom_fields['ContributionRecur'])) { $mandate_data += $custom_fields['ContributionRecur']; } + if (!empty($mandate_source = $profile->getAttribute('contribution_source'))) { + $mandate_data['source'] = $mandate_source; + } // Add cycle day for recurring contributions. if ($params['donation_rhythm'] != 'one_time') { @@ -610,6 +613,9 @@ function civicrm_api3_twingle_donation_Submit($params) { unset($mandate_data['reference']); } + // set campaign, subject to configuration + CRM_Twingle_Submission::setCampaign($mandate_data, 'mandate', $params, $profile); + // Create the mandate. $mandate = civicrm_api3('SepaMandate', 'createfull', $mandate_data); @@ -647,7 +653,10 @@ function civicrm_api3_twingle_donation_Submit($params) { $contribution_data += $custom_fields['ContributionRecur']; } - $contribution_recur = civicrm_api3('contributionRecur', 'create', $contribution_recur_data); + // set campaign, subject to configuration + CRM_Twingle_Submission::setCampaign($contribution_data, 'recurring', $params, $profile); + + $contribution_recur = civicrm_api3('ContributionRecur', 'create', $contribution_recur_data); if ($contribution_recur['is_error']) { throw new CiviCRM_API3_Exception( E::ts('Could not create recurring contribution.'), @@ -698,10 +707,19 @@ function civicrm_api3_twingle_donation_Submit($params) { $membership_type_id = $profile->getAttribute('membership_type_id'); } if (!empty($membership_type_id)) { - $membership = civicrm_api3('Membership', 'create', array( - 'contact_id' => $contact_id, - 'membership_type_id' => $membership_type_id, - )); + // create the membership + $membership_data = [ + 'contact_id' => $contact_id, + 'membership_type_id' => $membership_type_id, + ]; + // set campaign, subject to configuration + CRM_Twingle_Submission::setCampaign($membership_data, 'membership', $params, $profile); + // set source + if (!empty($membership_source = $profile->getAttribute('contribution_source'))) { + $membership_data['source'] = $membership_source; + } + + $membership = civicrm_api3('Membership', 'create', $membership_data); $result_values['membership'] = $membership; // call the postprocess API @@ -737,10 +755,10 @@ function civicrm_api3_twingle_donation_Submit($params) { } catch (CiviCRM_API3_Exception $ex) { // TODO: more error handling? - Civi::log()->debug("Twingle membership postprocessing call {$pp_entity}.{$pp_action} has failed: " . $ex->getMessage()); - throw new Exception( - E::ts("Twingle membership postprocessing call has failed, see log for more information") - ); + Civi::log()->warning("Twingle membership postprocessing call {$pp_entity}.{$pp_action} has failed: " . $ex->getMessage()); + throw new Exception( + E::ts("Twingle membership postprocessing call has failed, see log for more information") + ); } } } diff --git a/templates/CRM/Twingle/Form/Profile.tpl b/templates/CRM/Twingle/Form/Profile.tpl index 17e0c87..708cb5a 100644 --- a/templates/CRM/Twingle/Form/Profile.tpl +++ b/templates/CRM/Twingle/Form/Profile.tpl @@ -228,6 +228,11 @@ {$form.campaign.html} + + {$form.campaign_targets.label} + {$form.campaign_targets.html} + + {$form.membership_type_id.label} {$form.membership_type_id.html}