You are here

civicrm_case_activity_reference_field.module in CiviCRM Entity 7.2

Provide CiviCRM entity reference field type

File

modules/civicrm_case_activity_reference_field/civicrm_case_activity_reference_field.module
View source
<?php

/**
 * @file
 * Provide CiviCRM entity reference field type
 */

/**
 * Implements hook_field_info().
 *
 * @return array
 */
function civicrm_case_activity_reference_field_field_info() {
  return array(
    'civicase_activity_reference' => array(
      'label' => t('CiviCase Activity Reference'),
      'description' => t('This field references CiviCase activities in CiviCRM'),
      'settings' => array(),
      'instance_settings' => array(),
      'default_widget' => 'civicase_activity_reference_default_widget',
      'default_formatter' => 'civicase_activity_reference_default_formatter',
    ),
  );
}

/**
 * Implements hook_form_FORMID_alter().
 *
 * form id : field_ui_field_edit_form
 *
 * Alter Field Settings form to set cardinality to Unlimited, and disable the select widget
 *
 * Check the "delete reference" inline entity form option if that is the widget
 *
 * @param $form
 * @param $form_state
 */
function civicrm_case_activity_reference_field_form_field_ui_field_edit_form_alter(&$form, &$form_state) {
  if ($form['#field']['type'] == 'civicase_activity_reference') {
    $form['field']['cardinality']['#default_value'] = -1;
    $form['field']['cardinality']['#disabled'] = TRUE;
    if ($form['instance']['widget']['type']['#value'] == 'inline_entity_form_single' || $form['instance']['widget']['type']['#value'] == 'inline_entity_form') {
      $form['instance']['widget']['settings']['type_settings']['delete_references']['#default_value'] = 1;

      //$form['instance']['widget']['settings']['type_settings']['delete_references']['#disabled'] = TRUE;

      // Does it make sense to have the "add existing entities?" functionality, disabling it for now
      if (isset($form['instance']['widget']['settings']['type_settings']['allow_existing'])) {
        $form['instance']['widget']['settings']['type_settings']['allow_existing']['#default_value'] = 0;
        $form['instance']['widget']['settings']['type_settings']['allow_existing']['#disabled'] = TRUE;
      }
    }
  }
}

/**
 * Implements hook_form_FORMID_alter().
 *
 * form id : field_ui_field_overview_form
 *
 * Only allow creation of civicase_activity_reference field  for civicrm entities
 *
 * @param $form
 * @param $form_state
 */
function civicrm_case_activity_reference_field_form_field_ui_field_overview_form_alter(&$form, &$form_state) {
  if ($form['#entity_type'] != 'civicrm_case') {
    unset($form['fields']['_add_new_field']['type']['#options']['civicase_activity_reference']);
    foreach ($form['fields']['_add_existing_field']['field_name']['#options'] as $field_name => $description) {
      if (strpos($description, 'CiviCase Activity Reference:') !== 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_case_activity_reference_field_field_settings_form($field, $instance, $has_data) {
  $defaults = field_info_field_settings($field['type']);
  $settings = array_merge($defaults, $field['settings']);
  return;
}

/**
 * Implements hook_field_load().
 *
 * @param $entity_type
 * @param $entities
 * @param $field
 * @param $instances
 * @param $langcode
 * @param $items
 * @param $age
 */
function civicrm_case_activity_reference_field_field_load($entity_type, $entities, $field, $instances, $langcode, &$items, $age) {
  foreach ($entities as $id => $entity) {
    try {
      $query = db_select('civicrm_case_activity', 'ca');
      $query
        ->fields('ca', array(
        'activity_id',
      ));
      $query
        ->join('civicrm_activity', 'a', 'ca.activity_id = a.id');
      $activities = $query
        ->condition('ca.case_id', $id, '=')
        ->condition('a.is_current_revision', 1, '=')
        ->execute()
        ->fetchAll();
      $result = array();
      if (!empty($activities)) {
        foreach ($activities as $activity) {
          $result[] = $activity->activity_id;
        }
      }
    } catch (Exception $e) {
      $error = $e
        ->getMessage();
      drupal_set_message($error, 'error');
      continue;
    }
    if (!empty($result)) {
      foreach ($result as $delta => $activity_id) {
        $items[$id][$delta]['target_id'] = $activity_id;
      }
    }
  }
}

/**
 * Implements hook_field_insert().
 *
 * @param $entity_type
 * @param $entity
 * @param $field
 * @param $instance
 * @param $langcode
 * @param $items
 */
function civicrm_case_activity_reference_field_field_insert($entity_type, $entity, $field, $instance, $langcode, &$items) {
  foreach ($items as $delta => $item) {
    unset($items[$delta]);
  }
}

/**
 * Implements hook_field_update().
 *
 * @param $entity_type
 * @param $entity
 * @param $field
 * @param $instance
 * @param $langcode
 * @param $items
 */
function civicrm_case_activity_reference_field_field_update($entity_type, $entity, $field, $instance, $langcode, &$items) {
  foreach ($items as $delta => $item) {
    unset($items[$delta]);
  }
}

/**
 * Implements hook_field_widget_info().
 */
function civicrm_case_activity_reference_field_field_widget_info() {
  return array(
    'civicase_activity_reference_default_widget' => array(
      'label' => t('CiviCase Activity Reference Default Widget'),
      'field types' => array(
        'civicase_activity_reference',
      ),
      'settings' => array(),
      'behaviors' => array(
        'multiple values' => FIELD_BEHAVIOR_DEFAULT,
        'default value' => FIELD_BEHAVIOR_DEFAULT,
      ),
    ),
  );
}

/**
 * Implements hook_field_widget_info_alter().
 *
 * @param $info
 */
function civicrm_case_activity_reference_field_field_widget_info_alter(&$info) {
  $info['inline_entity_form']['field types'][] = 'civicase_activity_reference';
  $info['inline_entity_form_single']['field types'][] = 'civicase_activity_reference';
}

/**
 * Implements hook_inline_entity_form_settings_alter().
 *
 * @param $settings
 * @param $field
 * @param $instance
 */
function civicrm_case_activity_reference_field_inline_entity_form_settings_alter(&$settings, $field, $instance) {
  if ($field['type'] == 'civicase_activity_reference') {
    $settings['entity_type'] = 'civicrm_activity';
    $settings['column'] = 'target_id';
    $settings['bundles'] = array(
      'civicrm_activity',
    );
  }
}

/**
 * Implements hook_field_is_empty().
 *
 * @param $item
 * @param $field
 * @return bool
 */
function civicrm_case_activity_reference_field_field_is_empty($item, $field) {
  if (!isset($item['target_id']) || !is_numeric($item['target_id'])) {
    return TRUE;
  }
  return FALSE;
}

/**
 * Implements hook_field_widget_form().
 */
function civicrm_case_activity_reference_field_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
  $orig_element = $element;
  switch ($instance['widget']['type']) {
    case 'civicase_activity_reference_default_widget':
      $widget = array();
      $widget = $orig_element + array(
        '#type' => 'textfield',
        '#default_value' => isset($items[$delta]['target_id']) ? $items[$delta]['target_id'] : NULL,
      );
      $widget['#title'] = t('Target ID');
      $widget['#weight'] = 0;
      $element['target_id'] = $widget;
      break;
  }
  return $element;
}

/**
 * Implements hook_field_formatter_info().
 */
function civicrm_case_activity_reference_field_field_formatter_info() {
  return array(
    'civicase_activity_reference_default_formatter' => array(
      // Machine name of the formatter
      'label' => t('Referenced ID'),
      'field types' => array(
        'civicase_activity_reference',
      ),
      'settings' => array(),
    ),
    'civicase_activity_reference_entity_label_formatter' => array(
      // Machine name of the formatter
      'label' => t('Label'),
      'field types' => array(
        'civicase_activity_reference',
      ),
      'settings' => array(
        // Array of the settings we'll create
        'link_to_entity' => 0,
      ),
    ),
    'civicase_activity_reference_entity_formatter' => array(
      // Machine name of the formatter
      'label' => t('Rendered Entity'),
      'field types' => array(
        'civicase_activity_reference',
      ),
      'settings' => array(
        // Array of the settings we'll create
        'view_mode' => 'default',
      ),
    ),
  );
}

/**
 * Implements hook_field_formatter_settings_form().
 *
 * @param $field
 * @param $instance
 * @param $view_mode
 * @param $form
 * @param $form_state
 * @return array
 */
function civicrm_case_activity_reference_field_field_formatter_settings_form($field, $instance, $view_mode, $form, &$form_state) {
  if ($field['type'] == 'civicase_activity_reference') {
    $display = $instance['display'][$view_mode];
    $settings = $display['settings'];
    $target_entity_type = 'civicrm_activity';
    $modes = field_view_mode_settings($target_entity_type, $target_entity_type);
    $view_modes = array(
      'default' => 'default',
    );
    foreach ($modes as $key => $data) {
      $view_modes[$key] = $key;
    }
    $element = array();
    $element['view_mode'] = array(
      '#type' => 'select',
      '#title' => t('View mode'),
      '#description' => 'Select the view mode to render the Activity as.',
      '#options' => $view_modes,
      '#default_value' => isset($settings['view_mode']) ? $settings['view_mode'] : 'default',
    );
    $element['link_to_entity'] = array(
      '#type' => 'checkbox',
      '#title' => t('Output as link to entity'),
      '#default_value' => isset($settings['link_to_entity']) ? $settings['link_to_entity'] : 'default',
      '#return_value' => 1,
    );
    if ($display['type'] == 'civicase_activity_reference_entity_formatter') {
      $element['link_to_entity']['#access'] = FALSE;
    }
    elseif ($display['type'] == 'civicase_activity_reference_entity_label_formatter') {
      $element['view_mode']['#access'] = FALSE;
    }
    return $element;
  }
}

/**
 * Implements hook_field_formatter_settings_summary().
 *
 * @param $field
 * @param $instance
 * @param $view_mode
 * @return string
 */
function civicrm_case_activity_reference_field_field_formatter_settings_summary($field, $instance, $view_mode) {
  if ($field['type'] == 'civicase_activity_reference') {
    $display = $instance['display'][$view_mode];
    $settings = $display['settings'];
    $summary = '';
    if ($display['type'] == 'civicase_activity_reference_entity_formatter') {
      $summary = t('Target Entity @entity_type Rendered as : @data', array(
        '@entity_type' => 'civicrm_activity',
        '@data' => isset($settings['view_mode']) ? $settings['view_mode'] : 'default',
      ));
    }
    elseif ($display['type'] == 'civicase_activity_reference_entity_label_formatter') {
      $summary = t('Display @entity_type label as @data', array(
        '@entity_type' => 'civicrm_activity',
        '@data' => !empty($settings['link_to_entity']) ? 'link' : 'plain text.',
      ));
    }
    return $summary;
  }
}

/**
 * Implement hook_field_formatter_prepare_view().
 *
 * @param $entity_type
 * @param $entities
 * @param $field
 * @param $instances
 * @param $langcode
 * @param $items
 * @param $displays
 */
function civicrm_case_activity_reference_field_field_formatter_prepare_view($entity_type, $entities, $field, $instances, $langcode, &$items, $displays) {

  // this function borrowed pretty much straight from the entityreference module :)
  $target_ids = array();
  $target_entity_type = 'civicrm_activity';

  // Collect every possible entity attached to any of the entities.
  foreach ($entities as $id => $entity) {
    foreach ($items[$id] as $delta => $item) {
      if (isset($item['target_id'])) {
        $target_ids[] = $item['target_id'];
      }
    }
  }
  if ($target_ids) {
    $target_entities = entity_load($target_entity_type, $target_ids);
  }
  else {
    $target_entities = array();
  }

  // Iterate through the fieldable entities again to attach the loaded data.
  foreach ($entities as $id => $entity) {
    $rekey = FALSE;
    foreach ($items[$id] as $delta => $item) {

      // Check whether the referenced entity could be loaded.
      if (isset($target_entities[$item['target_id']])) {

        // Replace the instance value with the term data.
        $items[$id][$delta]['entity'] = $target_entities[$item['target_id']];

        // Check whether the user has access to the referenced entity.
        $has_view_access = entity_access('view', $target_entity_type, $target_entities[$item['target_id']]) !== FALSE;
        $has_update_access = entity_access('update', $target_entity_type, $target_entities[$item['target_id']]) !== FALSE;
        $items[$id][$delta]['access'] = $has_view_access || $has_update_access;
      }
      else {
        unset($items[$id][$delta]);
        $rekey = TRUE;
      }
    }
    if ($rekey) {

      // Rekey the items array.
      $items[$id] = array_values($items[$id]);
    }
  }
}

/**
 * Implements hook_field_formatter_view().
 */
function civicrm_case_activity_reference_field_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
  $element = array();
  $settings = $display['settings'];

  // Rebuild the items list to contain only those with access.
  foreach ($items as $key => $item) {
    if (empty($item['access'])) {
      unset($items[$key]);
    }
  }
  switch ($display['type']) {
    case 'civicase_activity_reference_default_formatter':
      foreach ($items as $delta => $item) {
        $element[$delta] = array(
          '#markup' => $item['target_id'],
        );
      }
      break;
    case 'civicase_activity_reference_entity_formatter':
      $target_entity_type = 'civicrm_activity';
      foreach ($items as $delta => $item) {
        static $depth = 0;
        $depth++;
        if ($depth > 20) {
          throw new EntityReferenceRecursiveRenderingException(t('Recursive rendering detected when rendering entity @entity_type(@entity_id). Aborting rendering.', array(
            '@entity_type' => $entity_type,
            '@entity_id' => $item['target_id'],
          )));
        }
        $entity_to_render = $item['entity'];
        unset($entity_to_render->content);
        $view_mode = isset($settings['view_mode']) ? $settings['view_mode'] : 'default';
        $content = entity_view($target_entity_type, array(
          $item['target_id'] => $entity_to_render,
        ), $view_mode, $langcode, FALSE);
        $depth = 0;
        $element[$delta] = $content;
      }
      break;
    case 'civicase_activity_reference_entity_label_formatter':
      $target_entity_type = 'civicrm_activity';
      foreach ($items as $delta => $item) {
        $output_as_link = !empty($settings['link_to_entity']) ? 1 : 0;
        $entity_text = entity_label($target_entity_type, $item['entity']);
        $entity_path = '/' . str_replace('_', '-', $target_entity_type) . '/' . $item['target_id'];
        if (empty($entity_text)) {
          $entity_text = ucwords(str_replace('_', ' ', $target_entity_type)) . 'id:' . $item['target_id'];
        }
        if ($output_as_link) {
          $element[$delta] = array(
            '#markup' => l($entity_text, $entity_path),
          );
        }
        else {
          $element[$delta] = array(
            '#markup' => $entity_text,
          );
        }
      }
      break;
  }
  return $element;
}

/**
 * Implements hook_civicrm_post().
 *
 * Clear specific entity field cache for entities that have fields of type civicase_activity_reference and target new or deleted entity
 *
 * @param $op
 * @param $objectName
 * @param $objectId
 * @param $objectRef
 */
function civicrm_case_activity_reference_field_civicrm_post($op, $objectName, $objectId, &$objectRef) {
  if ($op == 'create' || $op == 'delete' || $op == 'edit') {
    $civicrm_case_activity_reference_fields = db_select('field_config', 'fc')
      ->fields('fc', array(
      'field_name',
      'id',
    ))
      ->condition('type', 'civicase_activity_reference')
      ->execute();
    while ($record = $civicrm_case_activity_reference_fields
      ->fetchAssoc()) {
      $field = field_info_field_by_id($record['id']);
      $instances = db_select('field_config_instance', 'fi')
        ->fields('fi', array(
        'id',
        'entity_type',
      ))
        ->condition('field_id', $record['id'])
        ->execute();
      if ($objectName == 'Case') {
        while ($instance = $instances
          ->fetchAssoc()) {

          //clear the cache of entity
          cache_clear_all('field:' . $instance['entity_type'] . ':' . $objectId, 'cache_field');
        }
      }
      if ($objectName == 'Activity') {

        // look to see if this activity is associated with a case, if so we clear the field cache for the case
        while ($instance = $instances
          ->fetchAssoc()) {
          if (!empty($objectRef->case_id)) {
            cache_clear_all('field:' . $instance['entity_type'] . ':' . $objectRef->case_id, 'cache_field');
          }
        }
      }
    }
  }
}

/**
 * Implements hook_field_widget_form_alter().
 *
 * For CiviCRM Entity Add forms
 *
 * Unset field form for Inline Entity Form -- Single on entity create.
 * Disable widget buttons for Inline Entity Form -- Multiple on entity create.
 * Disable widget for default widget.
 *
 * @param $element
 * @param $form_state
 * @param $context
 */
function civicrm_case_activity_reference_field_field_widget_form_alter(&$element, &$form_state, $context) {
  if ($context['field']['type'] == 'civicase_activity_reference') {
    if ($context['instance']['widget']['type'] == 'inline_entity_form_single') {
      if (!empty($form_state['op']) && $form_state['op'] == 'create' || !empty($element['form']['#op']) && $element['form']['#op'] == 'add') {
        unset($element['form']);
      }
    }
    elseif ($context['instance']['widget']['type'] == 'inline_entity_form') {
      if (!empty($form_state['op']) && $form_state['op'] == 'create' || !empty($context['form']['#op']) && $context['form']['#op'] == 'add') {
        $element['actions']['ief_add']['#disabled'] = TRUE;
      }
    }
    elseif ($context['instance']['widget']['type'] == 'civicase_activity_reference_default_widget') {
      if ($form_state['op'] == 'create') {
        $element['#disabled'] = TRUE;
      }
    }
  }
}

/**
 * Implements hook_inline_entity_form_entity_form_alter().
 *
 * @param $entity_form
 * @param $form_state
 */
function civicrm_case_activity_reference_field_inline_entity_form_entity_form_alter(&$entity_form, &$form_state) {
  $ief_id = $entity_form['#ief_id'];
  $host_entity_type = $form_state['inline_entity_form'][$ief_id]['instance']['entity_type'];
  $field_info = array();
  foreach ($entity_form['#parents'] as $key => $parent) {
    if (strpos($parent, 'field_') === 0) {
      $field = field_info_field($parent);
      $instances = db_select('field_config_instance', 'fi')
        ->fields('fi', array(
        'id',
      ))
        ->condition('field_id', $field['id'])
        ->condition('entity_type', $host_entity_type)
        ->condition('bundle', $host_entity_type)
        ->execute();
      if ($instances
        ->rowCount()) {
        $field_name = $parent;
        $field_info = $field;
      }
    }
  }
  if (!empty($field_info) && $field_info['type'] == 'civicase_activity_reference') {

    // this doesn't handle a field that is nested on an entityreference field that is on say a node....
    // this handles the 'multi' widget
    if (isset($form_state['complete form']['id']['#default_value']) && isset($entity_form['case_id']) && is_array($entity_form['case_id'])) {
      if ($entity_form['#op'] == 'add' || $entity_form['#op'] == 'create' || $entity_form['#op'] == 'edit' || $entity_form['#op'] == 'update') {
        $entity_form['case_id']['#default_value'] = $form_state['complete form']['id']['#default_value'];
      }
      $entity_form['case_id']['#disabled'] = TRUE;
      if ($entity_form['#op'] == 'add' || $entity_form['#op'] == 'create') {
        $entity_form['is_current_revision']['#default_value'] = 1;
        $entity_form['is_current_revision']['#disabled'] = TRUE;
      }
    }
    elseif (isset($form_state['field'][$field_name][LANGUAGE_NONE]['instance']['entity_type'])) {
      if (isset($form_state['civicrm_case']->id)) {
        if ($entity_form['#op'] == 'add' || $entity_form['#op'] == 'create') {
          $entity_form['case_id']['#default_value'] = $form_state['civicrm_case']->id;
        }
        $entity_form['case_id']['#disabled'] = TRUE;
      }
    }

    //temporary ... necessary to disable target_id_column when civicase_activity_reference field is embedded on a entityreference field which is embedded on a node
    if (!empty($entity_form['case_id']['#default_value'])) {
      $entity_form['case_id']['#disabled'] = TRUE;
    }
  }
}

/**
 * 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_case_activity_reference_field_form_civicrm_entity_admin_settings_form_alter(&$form, &$form_state) {
  $required_entities = array(
    'civicrm_case' => 'Case',
    'civicrm_activity' => 'Activity',
  );
  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_case_activity_reference_field_admin_settings_form_validate';
}

/**
 * Validation callback for the CiviCRM Entity Enabled Entities form at 'admin/structure/civicrm-entity/settings'
 *
 * If CiviCRM Case Activity Reference module enabled, make sure activity, case entities are enabled
 * @param $form
 * @param $form_state
 */
function civicrm_case_activity_reference_field_admin_settings_form_validate($form, &$form_state) {
  $selected_entities = $form_state['values']['civicrm_entity_admin_enabled_entities'];
  $required_entities = array(
    'civicrm_case' => 'Case',
    'civicrm_activity' => 'Activity',
  );
  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 Case Activity Reference Field module');
    }
  }
}

Functions

Namesort descending Description
civicrm_case_activity_reference_field_admin_settings_form_validate Validation callback for the CiviCRM Entity Enabled Entities form at 'admin/structure/civicrm-entity/settings'
civicrm_case_activity_reference_field_civicrm_post Implements hook_civicrm_post().
civicrm_case_activity_reference_field_field_formatter_info Implements hook_field_formatter_info().
civicrm_case_activity_reference_field_field_formatter_prepare_view Implement hook_field_formatter_prepare_view().
civicrm_case_activity_reference_field_field_formatter_settings_form Implements hook_field_formatter_settings_form().
civicrm_case_activity_reference_field_field_formatter_settings_summary Implements hook_field_formatter_settings_summary().
civicrm_case_activity_reference_field_field_formatter_view Implements hook_field_formatter_view().
civicrm_case_activity_reference_field_field_info Implements hook_field_info().
civicrm_case_activity_reference_field_field_insert Implements hook_field_insert().
civicrm_case_activity_reference_field_field_is_empty Implements hook_field_is_empty().
civicrm_case_activity_reference_field_field_load Implements hook_field_load().
civicrm_case_activity_reference_field_field_settings_form Implements hook_field_settings_form().
civicrm_case_activity_reference_field_field_update Implements hook_field_update().
civicrm_case_activity_reference_field_field_widget_form Implements hook_field_widget_form().
civicrm_case_activity_reference_field_field_widget_form_alter Implements hook_field_widget_form_alter().
civicrm_case_activity_reference_field_field_widget_info Implements hook_field_widget_info().
civicrm_case_activity_reference_field_field_widget_info_alter Implements hook_field_widget_info_alter().
civicrm_case_activity_reference_field_form_civicrm_entity_admin_settings_form_alter Implements hook_form_FORM_ID_alter().
civicrm_case_activity_reference_field_form_field_ui_field_edit_form_alter Implements hook_form_FORMID_alter().
civicrm_case_activity_reference_field_form_field_ui_field_overview_form_alter Implements hook_form_FORMID_alter().
civicrm_case_activity_reference_field_inline_entity_form_entity_form_alter Implements hook_inline_entity_form_entity_form_alter().
civicrm_case_activity_reference_field_inline_entity_form_settings_alter Implements hook_inline_entity_form_settings_alter().