Merge branch 'dev_4'
[#4] Provide JSON parameter "custom_fields" with a configurable mapping to custom fields
This commit is contained in:
commit
aea1db611d
6 changed files with 191 additions and 1 deletions
|
@ -231,6 +231,13 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form {
|
||||||
array()
|
array()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
$this->add(
|
||||||
|
'textarea', // field type
|
||||||
|
'custom_field_mapping', // field name
|
||||||
|
E::ts('Custom field mapping'), // field label
|
||||||
|
array()
|
||||||
|
);
|
||||||
|
|
||||||
$this->addButtons(array(
|
$this->addButtons(array(
|
||||||
array(
|
array(
|
||||||
'type' => 'submit',
|
'type' => 'submit',
|
||||||
|
@ -268,6 +275,67 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form {
|
||||||
$errors['name'] = E::ts('Only alphanumeric characters and the underscore (_) are allowed for profile names.');
|
$errors['name'] = E::ts('Only alphanumeric characters and the underscore (_) are allowed for profile names.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Validate custom field mapping.
|
||||||
|
try {
|
||||||
|
$custom_field_mapping = preg_split('/\r\n|\r|\n/', $values['custom_field_mapping'], -1, PREG_SPLIT_NO_EMPTY);
|
||||||
|
if (!is_array($custom_field_mapping)) {
|
||||||
|
throw new Exception(
|
||||||
|
E::ts('Could not parse custom field mapping.')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
foreach ($custom_field_mapping as $custom_field_map) {
|
||||||
|
$custom_field_map = explode("=", $custom_field_map);
|
||||||
|
if (count($custom_field_map) !== 2) {
|
||||||
|
throw new Exception(
|
||||||
|
E::ts('Could not parse custom field mapping.')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
list($twingle_field_name, $custom_field_name) = $custom_field_map;
|
||||||
|
$custom_field_id = substr($custom_field_name, strlen('custom_'));
|
||||||
|
|
||||||
|
// Check for custom field existence
|
||||||
|
try {
|
||||||
|
$custom_field = civicrm_api3('CustomField', 'getsingle', array(
|
||||||
|
'id' => $custom_field_id,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
catch (CiviCRM_API3_Exception $exception) {
|
||||||
|
throw new Exception(
|
||||||
|
E::ts(
|
||||||
|
'Custom field custom_%1 does not exist.',
|
||||||
|
array(1 => $custom_field_id)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only allow custom fields on relevant entities.
|
||||||
|
try {
|
||||||
|
$custom_group = civicrm_api3('CustomGroup', 'getsingle', array(
|
||||||
|
'id' => $custom_field['custom_group_id'],
|
||||||
|
'extends' => array(
|
||||||
|
'IN' => array(
|
||||||
|
'Contact',
|
||||||
|
'Individual',
|
||||||
|
'Organization',
|
||||||
|
'Contribution',
|
||||||
|
'ContributionRecur',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
));
|
||||||
|
} catch (CiviCRM_API3_Exception $exception) {
|
||||||
|
throw new Exception(
|
||||||
|
E::ts(
|
||||||
|
'Custom field custom_%1 is not in a CustomGroup that extends one of the supported CiviCRM entities.',
|
||||||
|
array(1 => $custom_field['id'])
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception $exception) {
|
||||||
|
$errors['custom_field_mapping'] = $exception->getMessage();
|
||||||
|
}
|
||||||
|
|
||||||
return empty($errors) ? TRUE : $errors;
|
return empty($errors) ? TRUE : $errors;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -69,6 +69,21 @@ class CRM_Twingle_Profile {
|
||||||
return in_array($project_id, $project_ids);
|
return in_array($project_id, $project_ids);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
* The profile's configured custom field mapping
|
||||||
|
*/
|
||||||
|
public function getCustomFieldMapping() {
|
||||||
|
$custom_field_mapping = array();
|
||||||
|
if (!empty($custom_field_definition = $this->getAttribute('custom_field_mapping'))) {
|
||||||
|
foreach (preg_split('/\r\n|\r|\n/', $custom_field_definition, -1, PREG_SPLIT_NO_EMPTY) as $custom_field_map) {
|
||||||
|
list($twingle_field_name, $custom_field_name) = explode("=", $custom_field_map);
|
||||||
|
$custom_field_mapping[$twingle_field_name] = $custom_field_name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $custom_field_mapping;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves all data attributes of the profile.
|
* Retrieves all data attributes of the profile.
|
||||||
*
|
*
|
||||||
|
@ -191,6 +206,7 @@ class CRM_Twingle_Profile {
|
||||||
'donation_receipt_groups',
|
'donation_receipt_groups',
|
||||||
'campaign',
|
'campaign',
|
||||||
'contribution_source',
|
'contribution_source',
|
||||||
|
'custom_field_mapping',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -250,6 +266,7 @@ class CRM_Twingle_Profile {
|
||||||
'donation_receipt_groups' => NULL,
|
'donation_receipt_groups' => NULL,
|
||||||
'campaign' => NULL,
|
'campaign' => NULL,
|
||||||
'contribution_source' => NULL,
|
'contribution_source' => NULL,
|
||||||
|
'custom_field_mapping' => NULL,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -99,6 +99,16 @@ class CRM_Twingle_Submission {
|
||||||
}
|
}
|
||||||
$params['gender_id'] = $gender_id;
|
$params['gender_id'] = $gender_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Validate custom fields parameter, if given.
|
||||||
|
if (!empty($params['custom_fields'])) {
|
||||||
|
if (!is_array($custom_fields = json_decode($params['custom_fields'], TRUE))) {
|
||||||
|
throw new CiviCRM_API3_Exception(
|
||||||
|
E::ts('Invalid format for custom fields.'),
|
||||||
|
'invalid_format'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -238,6 +238,13 @@ function _civicrm_api3_twingle_donation_Submit_spec(&$params) {
|
||||||
'api.required' => 0,
|
'api.required' => 0,
|
||||||
'description' => E::ts('The CiviCRM ID of a campaign to assign the contribution.'),
|
'description' => E::ts('The CiviCRM ID of a campaign to assign the contribution.'),
|
||||||
);
|
);
|
||||||
|
$params['custom_fields'] = array(
|
||||||
|
'name' => 'custom_fields',
|
||||||
|
'title' => E::ts('Custom fields'),
|
||||||
|
'type' => CRM_Utils_Type::T_STRING,
|
||||||
|
'api.required' => 0,
|
||||||
|
'description' => E::ts('Additional information for either the contact or the (recurring) contribution.'),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -280,6 +287,27 @@ function civicrm_api3_twingle_donation_Submit($params) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Extract custom field values using the profile's mapping of Twingle fields
|
||||||
|
// to CiviCRM custom fields.
|
||||||
|
$custom_fields = array();
|
||||||
|
if (!empty($params['custom_fields'])) {
|
||||||
|
$custom_field_mapping = $profile->getCustomFieldMapping();
|
||||||
|
|
||||||
|
foreach (json_decode($params['custom_fields']) as $twingle_field => $value) {
|
||||||
|
if (isset($custom_field_mapping[$twingle_field])) {
|
||||||
|
// Get custom field definition to store values by entity the field
|
||||||
|
// extends.
|
||||||
|
$custom_field_id = substr($custom_field_mapping[$twingle_field], strlen('custom_'));
|
||||||
|
$custom_field = civicrm_api3('CustomField', 'getsingle', array(
|
||||||
|
'id' => $custom_field_id,
|
||||||
|
// Chain a CustomGroup.getsingle API call.
|
||||||
|
'api.CustomGroup.getsingle' => array(),
|
||||||
|
));
|
||||||
|
$custom_fields[$custom_field['api.CustomGroup.getsingle']['extends']][$custom_field_mapping[$twingle_field]] = $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Create contact(s).
|
// Create contact(s).
|
||||||
if ($params['is_anonymous']) {
|
if ($params['is_anonymous']) {
|
||||||
// Retrieve the ID of the contact to use for anonymous donations defined
|
// Retrieve the ID of the contact to use for anonymous donations defined
|
||||||
|
@ -351,6 +379,15 @@ function civicrm_api3_twingle_donation_Submit($params) {
|
||||||
$contact_data[$contact_component] = $params[$contact_param];
|
$contact_data[$contact_component] = $params[$contact_param];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add custom field values.
|
||||||
|
if (!empty($custom_fields['Contact'])) {
|
||||||
|
$contact_data += $custom_fields['Contact'];
|
||||||
|
}
|
||||||
|
if (!empty($custom_fields['Individual'])) {
|
||||||
|
$contact_data += $custom_fields['Individual'];
|
||||||
|
}
|
||||||
|
|
||||||
if (!$contact_id = CRM_Twingle_Submission::getContact(
|
if (!$contact_id = CRM_Twingle_Submission::getContact(
|
||||||
'Individual',
|
'Individual',
|
||||||
$contact_data
|
$contact_data
|
||||||
|
@ -375,6 +412,12 @@ function civicrm_api3_twingle_donation_Submit($params) {
|
||||||
$organisation_data = array(
|
$organisation_data = array(
|
||||||
'organization_name' => $params['organization_name'],
|
'organization_name' => $params['organization_name'],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Add custom field values.
|
||||||
|
if (!empty($custom_fields['Organization'])) {
|
||||||
|
$organisation_data += $custom_fields['Organization'];
|
||||||
|
}
|
||||||
|
|
||||||
if (!empty($submitted_address)) {
|
if (!empty($submitted_address)) {
|
||||||
$organisation_data += $submitted_address;
|
$organisation_data += $submitted_address;
|
||||||
// Use configured location type for organisation address.
|
// Use configured location type for organisation address.
|
||||||
|
@ -459,6 +502,11 @@ function civicrm_api3_twingle_donation_Submit($params) {
|
||||||
'total_amount' => $params['amount'] / 100,
|
'total_amount' => $params['amount'] / 100,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Add custom field values.
|
||||||
|
if (!empty($custom_fields['Contribution'])) {
|
||||||
|
$contribution_data += $custom_fields['Contribution'];
|
||||||
|
}
|
||||||
|
|
||||||
if (!empty($params['purpose'])) {
|
if (!empty($params['purpose'])) {
|
||||||
$contribution_data['note'] = $params['purpose'];
|
$contribution_data['note'] = $params['purpose'];
|
||||||
}
|
}
|
||||||
|
@ -512,6 +560,10 @@ function civicrm_api3_twingle_donation_Submit($params) {
|
||||||
)
|
)
|
||||||
// ... and frequency unit and interval from a static mapping.
|
// ... and frequency unit and interval from a static mapping.
|
||||||
+ CRM_Twingle_Submission::getFrequencyMapping($params['donation_rhythm']);
|
+ CRM_Twingle_Submission::getFrequencyMapping($params['donation_rhythm']);
|
||||||
|
// Add custom field values.
|
||||||
|
if (!empty($custom_fields['ContributionRecur'])) {
|
||||||
|
$mandate_data += $custom_fields['ContributionRecur'];
|
||||||
|
}
|
||||||
|
|
||||||
// Add cycle day for recurring contributions.
|
// Add cycle day for recurring contributions.
|
||||||
if ($params['donation_rhythm'] != 'one_time') {
|
if ($params['donation_rhythm'] != 'one_time') {
|
||||||
|
@ -543,6 +595,13 @@ function civicrm_api3_twingle_donation_Submit($params) {
|
||||||
'financial_type_id' => $profile->getAttribute('financial_type_id_recur'),
|
'financial_type_id' => $profile->getAttribute('financial_type_id_recur'),
|
||||||
)
|
)
|
||||||
+ CRM_Twingle_Submission::getFrequencyMapping($params['donation_rhythm']);
|
+ CRM_Twingle_Submission::getFrequencyMapping($params['donation_rhythm']);
|
||||||
|
|
||||||
|
// Add custom field values.
|
||||||
|
if (!empty($custom_fields['ContributionRecur'])) {
|
||||||
|
$contribution_recur_data += $custom_fields['ContributionRecur'];
|
||||||
|
$contribution_data += $custom_fields['ContributionRecur'];
|
||||||
|
}
|
||||||
|
|
||||||
$contribution_recur = civicrm_api3('contributionRecur', 'create', $contribution_recur_data);
|
$contribution_recur = civicrm_api3('contributionRecur', 'create', $contribution_recur_data);
|
||||||
if ($contribution_recur['is_error']) {
|
if ($contribution_recur['is_error']) {
|
||||||
throw new CiviCRM_API3_Exception(
|
throw new CiviCRM_API3_Exception(
|
||||||
|
|
|
@ -27,3 +27,17 @@
|
||||||
{htxt id='id-financial_type_id_recur'}
|
{htxt id='id-financial_type_id_recur'}
|
||||||
{ts domain="de.systopia.twingle"}Select which financial type to use for recurring contributions.{/ts}
|
{ts domain="de.systopia.twingle"}Select which financial type to use for recurring contributions.{/ts}
|
||||||
{/htxt}
|
{/htxt}
|
||||||
|
|
||||||
|
{htxt id='id-custom_field_mapping'}
|
||||||
|
{ts domain="de.systopia.twingle"}<p>Map Twingle custom fields to CiviCRM custom fields using the following format (each assignment in a separate line):</p>
|
||||||
|
<pre>twingle_field_1=custom_123<br />twingle_field_2=custom_789</pre>
|
||||||
|
<p>Always use the <code>custom_[id]</code> notation for CiviCRM custom fields.</p>
|
||||||
|
<p>Only custom fields extending one of the following CiviCRM entities are allowed:</p>
|
||||||
|
<ul>
|
||||||
|
<li><strong>Contact</strong> – Will be set on the Individual contact</li>
|
||||||
|
<li><strong>Individual</strong> – Will be set on the Individual contact</li>
|
||||||
|
<li><strong>Organization</strong> – Will be set on the Organization contact, if an organisation name was submitted</li>
|
||||||
|
<li><strong>Contribution</strong> – Will be set on the contribution</li>
|
||||||
|
<li><strong>ContributionRecur</strong> – Will be set on the recurring contribution and deriving single contributions</li>
|
||||||
|
</ul>{/ts}
|
||||||
|
{/htxt}
|
||||||
|
|
|
@ -161,7 +161,7 @@
|
||||||
|
|
||||||
<fieldset>
|
<fieldset>
|
||||||
|
|
||||||
<legend>{ts domain="de.systopia.twingle"}Groups{/ts}</legend>
|
<legend>{ts domain="de.systopia.twingle"}Groups and Correlations{/ts}</legend>
|
||||||
|
|
||||||
<table class="form-layout-compressed">
|
<table class="form-layout-compressed">
|
||||||
|
|
||||||
|
@ -190,6 +190,28 @@
|
||||||
<td class="content">{$form.contribution_source.html}</td>
|
<td class="content">{$form.contribution_source.html}</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
|
<tr class="crm-section">
|
||||||
|
<td class="label">
|
||||||
|
{$form.custom_field_mapping.label}
|
||||||
|
<a
|
||||||
|
onclick='
|
||||||
|
CRM.help(
|
||||||
|
"{ts domain="de.systopia.twingle"}Custom field mapping{/ts}",
|
||||||
|
{literal}{
|
||||||
|
"id": "id-custom_field_mapping",
|
||||||
|
"file": "CRM\/Twingle\/Form\/Profile"
|
||||||
|
}{/literal}
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
'
|
||||||
|
href="#"
|
||||||
|
title="{ts domain="de.systopia.twingle"}Help{/ts}"
|
||||||
|
class="helpicon"
|
||||||
|
></a>
|
||||||
|
</td>
|
||||||
|
<td class="content">{$form.custom_field_mapping.html}</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue