Commit c0c71421 authored by Mathieu Lutfy's avatar Mathieu Lutfy Committed by Aegir user
Browse files

Adds a few improvements to make sure that remoteform can handle formatting,...

Adds a few improvements to make sure that remoteform can handle formatting, contact-reference fields, groups field, etc.
parent 10a0e3de
......@@ -14,6 +14,20 @@ class CRM_Activityprofile_APIWrappers_Profile {
return $apiRequest;
}
// We hook into 'getfields' also, but only for the output.
if ($apiRequest['action'] != 'submit') {
return $apiRequest;
}
// Fix any ContactReference field, where we added an empty/zero value for the "- select -"
foreach ($apiRequest['fields'] as $key => $val) {
if ($val['data_type'] == 'ContactReference') {
if (empty($apiRequest['params'][$key])) {
unset($apiRequest['params'][$key]);
}
}
}
// This is a profile with activity fields, but without an activity_id
// Let's create a new contact and a new activity.
// We only do the minimum and let profile.submit do the rest.
......@@ -71,14 +85,144 @@ class CRM_Activityprofile_APIWrappers_Profile {
}
/**
*
* Fixes the metadata so that Profile.getfields works as expected
* for fields that are not part of the main entity (ex: Activity fields).
*/
public function toApiOutput($apiRequest, $result) {
if (empty($result['id'])) {
if ($apiRequest['action'] != 'getfields') {
return $result;
}
// Civi::log()->debug('toApiOutput: ' . print_r($apiRequest, 1) . ' --- ' . print_r($result, 1));
$params = $apiRequest['params'];
$profile_id = _civicrm_api3_profile_getProfileID($params['profile_id']);
foreach ($result['values'] as $key => &$val) {
if ($val['name'] == 'url' && empty($val['data_type'])) {
$val = civicrm_api3('Website', 'getfields')['values']['url'];
}
elseif (substr($val['name'], 0, 11) == 'formatting_') {
$val['type'] = 'formatting';
$val['html_type'] = 'formatting';
$val['entity'] = 'Contact';
}
elseif (empty($val['label']) && substr($val['name'], 0, 7) == 'custom_') {
$custom_field_id = substr($val['name'], 7);
// @todo Ugly code
try {
$val = civicrm_api3('Contact', 'getfield', [
'name' => $val['name'],
'action' => 'get',
])['values'];
$val['entity'] = 'Contact';
}
catch (Exception $e) {
}
if (empty($val['label'])) {
$val = civicrm_api3('Activity', 'getfield', [
'name' => $val['name'],
'action' => 'get',
])['values'];
$val['entity'] = 'Activity';
}
if (!empty($val['pseudoconstant'])) {
$val['options'] = [];
if ($val['html_type'] == 'Select') {
$val['options'][''] = ts('- select -');
}
$val['options'] += civicrm_api3($val['entity'], 'getoptions', [
'field' => $val['name'],
])['values'];
}
}
// Fix other metadata that might be missing from getfield above
// ex: weight, help_pre, help_post.
// @todo Is it a bug in core?
try {
$field = civicrm_api3('UFField', 'get', [
'uf_group_id' => $profile_id,
'field_name' => $val['name'],
'sequential' => 1,
])['values'][0];
if (empty($val['weight'])) {
$val['weight'] = $field['weight'];
}
if (empty($val['help_pre'])) {
$val['help_pre'] = $field['help_pre'] ?? '';
}
if (empty($val['help_post'])) {
$val['help_post'] = $field['help_post'] ?? '';
}
}
catch (Exception $e) {
}
// Fix ContactReference fields, since the site will not have select2
// or API access in general (anonymous users), we fetch all the possible
// options and treat it as a normal select field.
if ($val['data_type'] == 'ContactReference') {
$val['html_type'] = 'Select';
// Fetch the options
$filter = civicrm_api3('CustomField', 'getsingle', ['id' => $val['id']])['filter'];
$filterParams = [];
parse_str($filter, $filterParams);
$filterParams['options'] = ['limit' => 0];
$filterParams['return'] = ['id', 'display_name', 'sort' => 'sort_name ASC'];
$options = [];
$contacts = civicrm_api3('Contact', 'get', $filterParams)['values'];
foreach ($contacts as $c) {
// This seems rather wrong, but it ensures that we can later
// insert the "- select -" option at the top.
$options[$c['id']] = $c['display_name'];
}
// I give up, I have no idea why sorting does not work
$options[0] = ts('- select -');
asort($options);
$val['options'] = $options;
}
// Converts the group field into checkboxes, and filters the exposed groups
// using the "groupfields" extension.
if ($val['name'] == 'group_id') {
unset($val['html']);
$val['html_type'] = 'CheckBox';
$field = civicrm_api3('UFField', 'get', [
'uf_group_id' => $profile_id,
'field_name' => 'group',
'sequential' => 1,
])['values'][0];
// Part of the 'groupfields' extension
$active_groups = Civi::settings()->get('gfprofile_' . $field['id']);
if (!empty($active_groups)) {
foreach ($val['options'] as $k => $opt) {
if (!in_array($k, $active_groups)) {
unset($val['options'][$k]);
}
}
}
}
}
// Re-sort on weight. Make sure to preserve keys.
uasort($result['values'], function($a, $b) {
return $a['weight'] - $b['weight'];
});
return $result;
}
......
......@@ -13,7 +13,7 @@ Known issues:
Roadmap:
* Wishlist: Profile Admin UI: option to automatically assign the activity to a specific contact (ex: for a contact form, assign to the person who handles the contact form).
* Wishlist: Profile Admin UI: option to automatically assign the activity to a specific contact (ex: for a contact form, assign to the person who handles the contact form). Or could be done with civirules.
* Wishlist: Auto-dedupe (according to the profile settings).
The extension is licensed under [AGPL-3.0](LICENSE.txt).
......
......@@ -117,7 +117,7 @@ function activityprofile_civicrm_alterSettingsFolders(&$metaDataFolders = NULL)
*/
function activityprofile_civicrm_apiWrappers(&$wrappers, $apiRequest) {
// The APIWrapper is conditionally registered so that it runs only when appropriate
if ($apiRequest['entity'] == 'Profile' && $apiRequest['action'] == 'submit') {
if ($apiRequest['entity'] == 'Profile' && in_array($apiRequest['action'], ['submit', 'getfields'])) {
$wrappers[] = new CRM_Activityprofile_APIWrappers_Profile();
}
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment