civicrm_entity_contact_assign_rel_contact_field.module in CiviCRM Entity 7.2
Provide CiviCRM Entity Contact Assign Relationship Contacts List Field Type. Provides a widget for adding/removing a contacts relationships to a list of contacts.
File
modules/civicrm_entity_contact_assign_rel_contact_field/civicrm_entity_contact_assign_rel_contact_field.moduleView source
<?php
/**
* @file
* Provide CiviCRM Entity Contact Assign Relationship Contacts List Field Type. Provides a widget for adding/removing a contacts relationships to a list of contacts.
*/
/**
* Implements hook_field_info().
*
* @return array
*/
function civicrm_entity_contact_assign_rel_contact_field_field_info() {
$contact_subtypes = _civicrm_entity_contact_assign_rel_contact_field_get_subtypes("Organization");
return array(
'civicrm_entity_contact_assign_rel_contact_field' => array(
'label' => t('CiviCRM Entity Contact Assign Relationship Contact List'),
'description' => t('Provides a widget for adding/removing a contacts relationships to a configured list of contacts.'),
'settings' => array(
'relationship_type' => '',
'contact_type' => "Organization",
'contact_subtype' => reset($contact_subtypes),
'contacts' => array(),
),
'instance_settings' => array(),
'default_widget' => 'civicrm_entity_contact_assign_rel_contact_field_default_widget',
'default_formatter' => 'civicrm_entity_contact_assign_rel_contact_field_default_formatter',
),
);
}
/**
* Implements hook_form_FORMID_alter().
*
* form id : field_ui_field_edit_form
*
* Alter Field Settings form to set cardinality to 1 and disable the select widget
*
* @param $form
* @param $form_state
*/
function civicrm_entity_contact_assign_rel_contact_field_form_field_ui_field_edit_form_alter(&$form, &$form_state) {
if ($form['#field']['type'] == 'civicrm_entity_contact_assign_rel_contact_field') {
// field settings mods
$form['field']['cardinality']['#default_value'] = 1;
$form['field']['cardinality']['#disabled'] = TRUE;
}
}
/**
* Implements hook_form_FORMID_alter().
*
* form id : field_ui_field_overview_form
*
* Only allow creation of civicrm_entity_contact_assign_rel_contact_fields to civicrm_contact entity type
*
* @param $form
* @param $form_state
*/
function civicrm_entity_contact_assign_rel_contact_field_form_field_ui_field_overview_form_alter(&$form, &$form_state) {
if ($form['#entity_type'] != 'civicrm_contact') {
unset($form['fields']['_add_new_field']['type']['#options']['civicrm_entity_contact_assign_rel_contact_field']);
foreach ($form['fields']['_add_existing_field']['field_name']['#options'] as $field_name => $description) {
if (strpos($description, 'CiviCRM Entity Contact Assign Relationship Contact List') !== FALSE) {
unset($form['fields']['_add_existing_field']['field_name']['#options'][$field_name]);
}
}
}
}
/**
* Implements hook_field_settings_form().
*
* @param $field
* @param $instance
* @param $has_data
*/
function civicrm_entity_contact_assign_rel_contact_field_field_settings_form($field, $instance, $has_data) {
$defaults = field_info_field_settings($field['type']);
$settings = array_merge($defaults, $field['settings']);
civicrm_initialize();
try {
$result = civicrm_api3('RelationshipType', 'get', array(
'is_active' => 1,
'contact_type_b' => "Organization",
));
$relationship_types = array();
if ($result['count']) {
foreach ($result['values'] as $id => $relationship_type) {
$relationship_types[$id] = $relationship_type['description'];
}
}
} catch (CiviCRM_API3_Exception $e) {
$relationship_types = array();
}
try {
/*$result = civicrm_api3('ContactType', 'get', array(
'parent_id' => array('IS NULL' => 1),
));
$contact_types = array();
foreach($result['values'] as $id => $contact_type) {
$contact_types[$contact_type['label']] = $contact_type['label'];
}*/
$contact_types['Organization'] = 'Organization';
} catch (CiviCRM_API3_Exception $e) {
$contact_types = array();
}
$contact_subtypes = _civicrm_entity_contact_assign_rel_contact_field_get_subtypes($settings['contact_type']);
$contacts = _civicrm_entity_contact_assign_rel_contact_field_get_contacts($settings['contact_type'], $settings['contact_subtype']);
$form['relationship_type'] = array(
'#type' => 'select',
'#title' => t('Relationship Type'),
'#default_value' => $settings['relationship_type'],
'#description' => t('Relationships types to include for this field '),
'#options' => $relationship_types,
);
$form['contact_type'] = array(
'#type' => 'select',
'#title' => 'Contact Type',
'#description' => t('Contact Type'),
'#default_value' => $settings['contact_type'],
'#options' => $contact_types,
'#ajax' => array(
'event' => 'change',
'wrapper' => 'contact-subtype-wrapper',
'callback' => 'civicrm_entity_contact_assign_rel_contact_field_contact_subtype_ajax_callback',
'method' => 'replace',
),
);
$form['contact_subtype'] = array(
'#type' => 'select',
'#title' => 'Contact Sub Type',
'#description' => t('Choose a contact subtype'),
'#default_value' => $settings['contact_subtype'],
'#options' => $contact_subtypes,
'#prefix' => '<div id="contact-subtype-wrapper">',
'#suffix' => '</div>',
'#validated' => TRUE,
'#ajax' => array(
'event' => 'change',
'wrapper' => 'contacts-wrapper',
'callback' => 'civicrm_entity_contact_assign_rel_contact_field_contacts_ajax_callback',
'method' => 'replace',
),
);
$form['contacts'] = array(
'#type' => 'select',
'#title' => 'Contacts',
'#description' => t('Choose contacts for this field to manage relationships with.'),
'#default_value' => $settings['contacts'],
'#options' => $contacts,
'#multiple' => TRUE,
'#prefix' => '<div id="contacts-wrapper">',
'#suffix' => '</div>',
);
return $form;
}
/**
* Ajax callback for contact subtype options
*
* @param $form
* @param $form_state
* @return mixed
*/
function civicrm_entity_contact_assign_rel_contact_field_contact_subtype_ajax_callback(&$form, &$form_state) {
$contact_type = $form_state['values']['field']['settings']['contact_type'];
$contact_subtypes = _civicrm_entity_contact_assign_rel_contact_field_get_subtypes($contact_type);
$form['field']['settings']['contact_subtype']['#options'] = $contact_subtypes;
return $form['field']['settings']['contact_subtype'];
}
/**
* Ajax callback for contacts options
*
* @param $form
* @param $form_state
* @return mixed
*/
function civicrm_entity_contact_assign_rel_contact_field_contacts_ajax_callback(&$form, &$form_state) {
$contact_type = $form_state['values']['field']['settings']['contact_type'];
$contact_subtype = $form_state['values']['field']['settings']['contact_subtype'];
$contacts = _civicrm_entity_contact_assign_rel_contact_field_get_contacts($contact_type, $contact_subtype);
$form['field']['settings']['contacts']['#options'] = $contacts;
return $form['field']['settings']['contacts'];
}
/**
* Utility function to fetch subtypes for a contact type
*
* @param $contact_type
* @return array
*/
function _civicrm_entity_contact_assign_rel_contact_field_get_subtypes($contact_type) {
civicrm_initialize();
try {
$result = civicrm_api3('ContactType', 'get', array(
'parent_id' => $contact_type,
));
$contact_subtypes = array();
foreach ($result['values'] as $id => $subtype) {
$contact_subtypes[$subtype['label']] = $subtype['label'];
}
} catch (CiviCRM_API3_Exception $e) {
$contact_subtypes = array();
}
return $contact_subtypes;
}
/**
* Helper function to fetch list of contacts
*
* @param $contact_type
* @param $contact_subtype
* @return array
*/
function _civicrm_entity_contact_assign_rel_contact_field_get_contacts($contact_type, $contact_subtype) {
civicrm_initialize();
$contacts = array();
try {
$result = civicrm_api3('Contact', 'get', array(
'contact_type' => $contact_type,
'contact_sub_type' => $contact_subtype,
));
if ($result['count']) {
foreach ($result['values'] as $id => $contact) {
$contacts[$id] = $contact['display_name'];
}
}
} catch (CiviCRM_API3_Exception $e) {
}
return $contacts;
}
/**
* Implements hook_field_load().
*
* @param $entity_type
* @param $entities
* @param $field
* @param $instances
* @param $langcode
* @param $items
* @param $age
*/
function civicrm_entity_contact_assign_rel_contact_field_field_load($entity_type, $entities, $field, $instances, $langcode, &$items, $age) {
if ($entity_type == 'civicrm_contact') {
$relationship_type_id = $field['settings']['relationship_type'];
$field_contact_options = _civicrm_entity_contact_assign_rel_contact_field_get_field_settings_contacts($field);
civicrm_initialize();
foreach ($entities as $entity_id => $entity) {
$contact_a_id = $entity->contact_id;
foreach ($field_contact_options as $contact_b_id => $name) {
try {
$result = civicrm_api3('Relationship', 'get', array(
'contact_id_a' => $contact_a_id,
'contact_id_b' => $contact_b_id,
'relationship_type_id' => $relationship_type_id,
'is_active' => 1,
));
if ($result['count']) {
$items[$entity_id][0]['contacts'][$contact_b_id] = $contact_b_id;
}
else {
$items[$entity_id][0]['contacts'][$contact_b_id] = 0;
}
} catch (CiviCRM_API3_Exception $e) {
continue;
}
}
}
}
}
/**
* Implements hook_field_insert().
*
* @param $entity_type
* @param $entity
* @param $field
* @param $instance
* @param $langcode
* @param $items
*/
function civicrm_entity_contact_assign_rel_contact_field_field_insert($entity_type, $entity, $field, $instance, $langcode, &$items) {
if ($entity_type == 'civicrm_contact') {
if (!empty($items[0]['contacts'])) {
if (!empty($entity->id)) {
$contact_a_id = $entity->id;
_civicrm_entity_contact_assign_rel_contact_field_process_field_items($contact_a_id, $field, $items);
}
}
}
}
/**
* Implements hook_field_update().
*
* @param $entity_type
* @param $entity
* @param $field
* @param $instance
* @param $langcode
* @param $items
*/
function civicrm_entity_contact_assign_rel_contact_field_field_update($entity_type, $entity, $field, $instance, $langcode, &$items) {
if ($entity_type == 'civicrm_contact') {
if (!empty($items[0]['contacts'])) {
if (!empty($entity->id)) {
$contact_a_id = $entity->id;
_civicrm_entity_contact_assign_rel_contact_field_process_field_items($contact_a_id, $field, $items);
}
}
}
}
/**
* Implements hook_field_widget_info().
*/
function civicrm_entity_contact_assign_rel_contact_field_field_widget_info() {
return array(
'civicrm_entity_contact_assign_rel_contact_field_checkboxes_widget' => array(
'label' => t('Checkboxes'),
'field types' => array(
'civicrm_entity_contact_assign_rel_contact_field',
),
'settings' => array(),
'behaviors' => array(
'multiple values' => FIELD_BEHAVIOR_DEFAULT,
'default value' => FIELD_BEHAVIOR_DEFAULT,
),
),
'civicrm_entity_contact_assign_rel_contact_field_radios_widget' => array(
'label' => t('Radios'),
'field types' => array(
'civicrm_entity_contact_assign_rel_contact_field',
),
'settings' => array(),
'behaviors' => array(
'multiple values' => FIELD_BEHAVIOR_DEFAULT,
'default value' => FIELD_BEHAVIOR_DEFAULT,
),
),
);
}
/**
* Implements hook_field_is_empty().
*
* @param $item
* @param $field
* @return bool
*/
function civicrm_entity_contact_assign_rel_contact_field_field_is_empty($item, $field) {
if (!empty($item['contacts'])) {
if (is_array($item['contacts'])) {
foreach ($item['contacts'] as $id => $value) {
if ($value) {
return FALSE;
}
}
}
elseif ($item['contacts']) {
return FALSE;
}
}
return TRUE;
}
/**
* Implements hook_field_widget_form().
*/
function civicrm_entity_contact_assign_rel_contact_field_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
$orig_element = $element;
$options = _civicrm_entity_contact_assign_rel_contact_field_get_field_settings_contacts($field);
$values = array();
if (!empty($items[$delta]['contacts'])) {
foreach ($items[$delta]['contacts'] as $contact_b_id => $value) {
$values[$contact_b_id] = $value;
}
}
switch ($instance['widget']['type']) {
case 'civicrm_entity_contact_assign_rel_contact_field_checkboxes_widget':
$widget = array();
$widget = $orig_element + array(
'#type' => 'checkboxes',
'#default_value' => $values,
'#options' => $options,
);
$widget['#title'] = $instance['label'];
$widget['#weight'] = 0;
$element['contacts'] = $widget;
break;
case 'civicrm_entity_contact_assign_rel_contact_field_radios_widget':
$default_value = 0;
foreach ($values as $contact_id => $value) {
if ($value) {
$default_value = $contact_id;
break;
}
}
$widget = array();
$widget = $orig_element + array(
'#type' => 'radios',
'#default_value' => $default_value,
'#options' => $options,
);
$widget['#title'] = $instance['label'];
$widget['#weight'] = 0;
$element['contacts'] = $widget;
break;
}
return $element;
}
/**
* Implements hook_field_formatter_info().
*/
function civicrm_entity_contact_assign_rel_contact_field_field_formatter_info() {
return array(
'civicrm_entity_contact_assign_rel_contact_field_default_formatter' => array(
// Machine name of the formatter
'label' => t('List Relationships'),
'field types' => array(
'civicrm_entity_contact_assign_rel_contact_field',
),
'settings' => array(
// Array of the settings we'll create
'link_to_relationships' => 0,
),
),
);
}
/**
* Implements hook_field_formatter_settings_form().
*
* @param $field
* @param $instance
* @param $view_mode
* @param $form
* @param $form_state
* @return array
*/
function civicrm_entity_contact_assign_rel_contact_field_field_formatter_settings_form($field, $instance, $view_mode, $form, &$form_state) {
if ($field['type'] == 'civicrm_entity_contact_assign_rel_contact_field') {
$display = $instance['display'][$view_mode];
$settings = $display['settings'];
$element = array();
$element['link_to_relationships'] = array(
'#type' => 'checkbox',
'#title' => t('Output Relationships as links to entities'),
'#default_value' => isset($settings['link_to_relationships']) ? $settings['link_to_relationships'] : 0,
'#return_value' => 1,
);
return $element;
}
}
/**
* Implements hook_field_formatter_settings_summary().
*
* @param $field
* @param $instance
* @param $view_mode
* @return string
*/
function civicrm_entity_contact_assign_rel_contact_field_field_formatter_settings_summary($field, $instance, $view_mode) {
if ($field['type'] == 'civicrm_entity_contact_assign_rel_contact_field') {
$display = $instance['display'][$view_mode];
$settings = $display['settings'];
$summary = '';
if ($display['type'] == 'civicrm_entity_contact_assign_rel_contact_field_default_formatter') {
$summary = t('Link to relationship: @data', array(
'@data' => !empty($settings['link_to_relationships']) ? 'Yes' : 'No',
));
}
return $summary;
}
}
/**
* Implements hook_field_formatter_view().
*/
function civicrm_entity_contact_assign_rel_contact_field_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
$element = array();
$settings = $display['settings'];
switch ($display['type']) {
case 'civicrm_entity_contact_assign_rel_contact_field_default_formatter':
$output_as_link = !empty($settings['link_to_relationships']) ? 1 : 0;
$relationship_type_id = $field['settings']['relationship_type'];
foreach ($items as $delta => $item) {
$markup = '';
foreach ($item['contacts'] as $contact_b_id => $value) {
if ($value) {
try {
$relationship_result = civicrm_api3('Relationship', 'getvalue', array(
'return' => "id",
'relationship_type_id' => $relationship_type_id,
'contact_id_a' => $entity->contact_id,
'contact_id_b' => $contact_b_id,
'is_active' => 1,
));
$relationship_type_result = civicrm_api3('Contact', 'getvalue', array(
'return' => "display_name",
'id' => $contact_b_id,
));
} catch (CiviCRM_API3_Exception $e) {
continue;
}
$relationship_id = $relationship_result;
if ($output_as_link) {
$relationship_path = 'civicrm-relationship' . '/' . $relationship_id;
$markup .= '<div class="civicrm-relationship-item">' . l($relationship_type_result, $relationship_path) . '</div>';
}
else {
$markup .= '<div class="civicrm-relationship-item">' . $relationship_type_result . '</div>';
}
}
}
if ($markup != '') {
$element[$delta] = array(
'#markup' => $markup,
);
}
}
break;
}
return $element;
}
/**
* Implements hook_civicrm_post().
*
* Here we need to probably clear some field caches when contacts are added / removed from group
*
* @param $op
* @param $objectName
* @param $objectId
* @param $objectRef
*/
function civicrm_entity_contact_assign_rel_contact_field_civicrm_post($op, $objectName, $objectId, &$objectRef) {
if ($objectName == 'Relationship' && ($op == 'create' || $op == 'delete' || $op == 'edit')) {
$fields = db_select('field_config', 'fc')
->fields('fc', array(
'id',
))
->condition('type', 'civicrm_entity_contact_assign_rel_contact_field')
->execute();
$contact_a_id = $objectRef->contact_id_a;
if ($fields
->rowCount()) {
cache_clear_all('field:civicrm_contact:' . $contact_a_id, 'cache_field');
}
}
}
/**
* Helper function to process field items on entity insert or update
*
* @param $contact_a_id
* @param $field
* @param $items
*/
function _civicrm_entity_contact_assign_rel_contact_field_process_field_items($contact_a_id, $field, &$items) {
$field_settings_contacts = array_keys(_civicrm_entity_contact_assign_rel_contact_field_get_field_settings_contacts($field));
$relationship_type_id = $field['settings']['relationship_type'];
if (!is_array($items[0]['contacts'])) {
$set_value = $items[0]['contacts'];
$items[0]['contacts'] = array();
foreach ($field_settings_contacts as $contact_b_id) {
if ($contact_b_id == $set_value) {
$items[0]['contacts'][$contact_b_id] = $set_value;
}
else {
$items[0]['contacts'][$contact_b_id] = 0;
}
}
}
foreach ($items[0]['contacts'] as $contact_b_id => $value) {
// ignore any programmatically added contact id keys that aren't in the field settings list
if (in_array($contact_b_id, $field_settings_contacts)) {
// if group id has a non-zero, check to see if contact has relationship, and if not, create it
if ($value) {
if (!_civicrm_entity_contact_assign_rel_contact_field_contact_has_relationship($contact_a_id, $contact_b_id, $relationship_type_id)) {
_civicrm_entity_contact_assign_rel_contact_field_add_contact_relationship($contact_a_id, $contact_b_id, $relationship_type_id);
}
}
else {
if (_civicrm_entity_contact_assign_rel_contact_field_contact_has_relationship($contact_a_id, $contact_b_id, $relationship_type_id)) {
_civicrm_entity_contact_assign_rel_contact_field_remove_contact_relationship($contact_a_id, $contact_b_id, $relationship_type_id);
}
}
}
}
}
/**
* Helper function to get an array of Contact Display Names keyed by contact id
*
* @param $field
* @return array
*/
function _civicrm_entity_contact_assign_rel_contact_field_get_field_settings_contacts($field) {
civicrm_initialize();
$contacts = array();
foreach ($field['settings']['contacts'] as $id => $contact_id) {
try {
$result = civicrm_api3('Contact', 'getvalue', array(
'return' => "display_name",
'id' => $contact_id,
));
$contacts[$id] = $result;
} catch (CiviCRM_API3_Exception $e) {
continue;
}
}
return $contacts;
}
/**
* Helper function to check if contact is in a group
*
* @param $contact_a_id
* @param $contact_b_id
* @param $relationship_type_id
* @return bool
*/
function _civicrm_entity_contact_assign_rel_contact_field_contact_has_relationship($contact_a_id, $contact_b_id, $relationship_type_id) {
civicrm_initialize();
try {
$result = civicrm_api3('Relationship', 'get', array(
'contact_id_a' => $contact_a_id,
'contact_id_b' => $contact_b_id,
'relationship_type_id' => $relationship_type_id,
'is_active' => 1,
));
} catch (CiviCRM_API3_Exception $e) {
return FALSE;
}
if ($result['count']) {
return TRUE;
}
else {
return FALSE;
}
}
/**
* Helper function, add a contact relationship added and set active with start date of "now"
*
* @param $contact_a_id
* @param $contact_b_id
* @param $relationship_type_id
*/
function _civicrm_entity_contact_assign_rel_contact_field_add_contact_relationship($contact_a_id, $contact_b_id, $relationship_type_id) {
civicrm_initialize();
try {
$start_date = date('Y-m-d');
$result = civicrm_api3('Relationship', 'create', array(
'contact_id_a' => $contact_a_id,
'contact_id_b' => $contact_b_id,
'relationship_type_id' => $relationship_type_id,
'is_active' => 1,
'start_date' => $start_date,
));
} catch (CiviCRM_API3_Exception $e) {
}
}
/**
* Helper function, set a relationship to inactive and set end date to "now"
*
* @param $contact_a_id
* @param $contact_b_id
* @param $relationship_type_id
*/
function _civicrm_entity_contact_assign_rel_contact_field_remove_contact_relationship($contact_a_id, $contact_b_id, $relationship_type_id) {
civicrm_initialize();
try {
$end_date = date('Y-m-d');
$relationship_result = civicrm_api3('Relationship', 'get', array(
'relationship_type_id' => $relationship_type_id,
'contact_id_a' => $contact_a_id,
'contact_id_b' => $contact_b_id,
));
if ($relationship_result['count']) {
$params = array(
'id' => $relationship_result['id'],
'contact_id_a' => $contact_a_id,
'contact_id_b' => $contact_b_id,
'relationship_type_id' => $relationship_type_id,
'is_active' => 0,
'end_date' => $end_date,
);
}
$result = civicrm_api3('Relationship', 'create', $params);
} catch (CiviCRM_API3_Exception $e) {
}
}
/**
* Implements hook_form_FORM_ID_alter().
*
* Alter the CiviCRM Entity enabled entities settings form
*
* Insure necessary entity types for this module remain enabled
*
* @param $form
* @param $form_state
*/
function civicrm_entity_contact_assign_rel_contact_field_form_civicrm_entity_admin_settings_form_alter(&$form, &$form_state) {
$required_entities = array(
'civicrm_contact' => 'Contact',
'civicrm_relationship' => 'Relationship',
);
foreach ($required_entities as $drupal_entity_type => $entity_type_label) {
if (empty($selected_entities[$drupal_entity_type])) {
$form['civicrm_entity_admin_enabled_entities'][$drupal_entity_type]['#disabled'] = TRUE;
$form['civicrm_entity_admin_enabled_entities'][$drupal_entity_type]['#default_value'] = 1;
}
}
$form['#validate'][] = 'civicrm_entity_contact_assign_rel_contact_field_admin_settings_form_validate';
}
/**
* Validation callback for the CiviCRM Entity Enabled Entities form at 'admin/structure/civicrm-entity/settings'
*
* @param $form
* @param $form_state
*/
function civicrm_entity_contact_assign_rel_contact_field_admin_settings_form_validate($form, &$form_state) {
$selected_entities = $form_state['values']['civicrm_entity_admin_enabled_entities'];
$required_entities = array(
'civicrm_contact' => 'Contact',
'civicrm_relationship' => 'Relationship',
);
foreach ($required_entities as $drupal_entity_type => $entity_type_label) {
if (empty($selected_entities[$drupal_entity_type])) {
form_set_error('civicrm_entity_admin_enabled_entities][' . $drupal_entity_type, $entity_type_label . ' required by CiviCRM Entity Contact Assign Relationship to Contact Field module');
}
}
}