You are here

crm_core_relationship.module in CRM Core 8.2

CRM Core Relationship, handles relationship logic and API.

CRM Core relationship is built on relation and CRM Core, it allows creation of relationship between contacts

File

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

/**
 * @file
 * CRM Core Relationship, handles relationship logic and API.
 *
 * CRM Core relationship is built on relation and CRM Core, it allows
 * creation of relationship between contacts
 */
use Drupal\crm_core_contact\Entity\ContactType;
use Drupal\collect\Entity\RelationType;

/**
 * Implements hook_permission().
 */
function crm_core_relationship_permission() {
  $permissions = array();

  // administration permission
  $permissions['administer contact relationship types'] = array(
    'title' => t('Administer contact relationship types'),
    'description' => t('Allows user to create/edit/delete any contact relationship types'),
    'restrict access' => TRUE,
  );

  // static permissions
  $permissions['create relation entities of any contact relationship'] = array(
    'title' => t('Create Any Contact Relationships'),
    'description' => t('Allows user to create any CRM relationship.'),
  );
  $permissions['view relation entities of any contact relationship'] = array(
    'title' => t('View Any Contact Relationships'),
    'description' => t('Allows user to view any CRM relationship'),
  );
  $permissions['edit relation entities of any contact relationship'] = array(
    'title' => t('Edit Any Contact Relationships'),
    'description' => t('Allows user to edit any CRM relationship'),
  );

  // per bundle permissions
  $relationships = crm_core_relationship_get_relationships();
  $entity_info = array(
    'permission labels' => array(
      'singular' => t('relationship'),
      'plural' => t('relationships'),
    ),
  );
  foreach ($relationships as $type => $info) {
    $info = (array) $info;
    $permissions += crm_core_bundle_access_permissions($type, $info, 'relation', $entity_info);
  }
  return $permissions;
}

/**
 * Implements hook crm_core_contact_delete
 */
function crm_core_relationship_crm_core_contact_delete($crm_core_contact) {

  // delete the relationship for a contact when the contact is deleted
  $query = relation_query('crm_core_contact', $crm_core_contact->contact_id);
  $results = $query
    ->execute();

  // delete each relationship
  foreach ($results as $relation) {
    $relation
      ->delete();
  }
}

/**
 * Access callback for all relationship permissions
 *
 * @return array $permissions
 */
function crm_core_relationship_access_permissions($relation_type, $op = 'create') {

  // $administer_relation_types = user_access('administer relation types');
  $administer_relationship_types = user_access('administer contact relationship types');
  if (is_object($relation_type)) {
    $bundle = $relation_type->relation_type;
  }
  else {
    $bundle = $relation_type;
  }
  switch ($op) {
    case 'admin':
      return $administer_relationship_types;
      break;

    // We are just viewing the list of relationships a contact has here
    case 'view_list':
      $view_any_relationship = user_access('view relation entities of any contact relationship');
      return $administer_relationship_types || $view_any_relationship;
      break;
    case 'view':

      // view a single relationship
      $view_any_relationship = user_access('view relation entities of any contact relationship');
      $view_type_relationship = user_access('view relation entities of bundle ' . $bundle);
      return $administer_relationship_types || $view_any_relationship || $view_type_relationship;
      break;
    case 'create_view':

      // we just need any of the create permissions
      $create_any_relationship = user_access('create relation entities of any contact relationship');
      $relationships = crm_core_relationship_get_relationships();
      $relationship_types = array_keys($relationships);
      foreach ($relationship_types as $type) {
        $create_type_relationship[] = user_access('create relation entities of bundle ' . $type);
      }

      // they just need any type of contact type create permission
      $create_type_relationship_flag = in_array(TRUE, $create_type_relationship);
      return $administer_relationship_types || $create_any_relationship || $create_type_relationship_flag;
      break;
    case 'create':
    default:
      $create_any_relationship = user_access('create relation entities of any contact relationship');
      $create_type_relationship = user_access('create relation entities of bundle ' . $bundle);
      return $administer_relationship_types || $create_any_relationship || $create_type_relationship;
      break;
  }
  return FALSE;
}

/**
 * Return contact types available for specific relationship type.
 *
 * @param $relation_type
 *   Relation type object.
 * @param $reverse
 *   Whether relationship is reversed.
 */
function crm_core_relationship_load_contact_types($relation_type, $reverse = 0) {

  // Check if it is a relationship type
  if (!crm_core_relationship_is_relationship_type($relation_type->relation_type)) {
    return array();
  }
  $contact_types = ContactType::loadMultiple();
  $bundles = $relation_type->directional && $reverse ? $relation_type->target_bundles : $relation_type->source_bundles;
  if (in_array('crm_core_contact:*', $bundles)) {
    return $contact_types;
  }
  $available_contact_types = array();
  foreach ($bundles as $bundle) {
    list($entity, $type) = explode(':', $bundle);
    $available_contact_types[$type] = $contact_types[$type];
  }
  return $available_contact_types;
}

/**
 * Return relationship types that can be applied to specific contact type.
 *
 * @param type $contact_type
 *   CRM contact type name.
 * @param type $reverse
 *   Whether relationship is reversed.
 */
function crm_core_relationship_load_relationship_types($contact_type, $reverse = 0) {
  $relation_types = RelationType::loadMultiple();
  $available_relationship_types = array();
  foreach ($relation_types as $relation_type) {
    if (!crm_core_relationship_is_relationship_type($relation_type->relation_type)) {
      continue;
    }
    $bundles = $reverse ? $relation_type->target_bundles : $relation_type->source_bundles;
    if (in_array('crm_core_contact:' . $contact_type, $bundles) || in_array('crm_core_contact:*', $bundles)) {
      $available_relationship_types[] = $relation_type;
    }
  }
  return $available_relationship_types;
}

/**
 * Check if relation_type is CRM relationship_type.
 *
 * @param $relation_type
 *   Relation type name or relation object provided by Relation module.
 */
function crm_core_relationship_is_relationship_type($relation_type) {
  static $types = array();
  if (is_object($relation_type)) {
    $relation_type_object = $relation_type;
    $relation_type = $relation_type_object->relation_type;
  }
  if (isset($types[$relation_type])) {
    return $types[$relation_type];
  }
  if (!isset($relation_type_object)) {
    $relation_type_object = RelationType::load($relation_type);
  }
  if ($relation_type_object) {
    $ret = TRUE;

    // It should be between CRM contact types only
    $ret = $ret && crm_core_relationship_is_contact_bundles($relation_type_object->source_bundles);
    if ($relation_type_object->directional) {
      $ret = $ret && crm_core_relationship_is_contact_bundles($relation_type_object->target_bundles);
    }

    // Arity should be equal to 2
    $ret = $ret && $relation_type_object->min_arity == 2 && $relation_type_object->max_arity == 2;
    $types[$relation_type] = $ret;
    return $ret;
  }
  return FALSE;
}

/**
 * Return true if there is only CRM contacts in relation type bundles.
 *
 * @param $bundles
 *   Array of relation type bundles.
 */
function crm_core_relationship_is_contact_bundles($bundles) {
  foreach ($bundles as $bundle) {
    list($entity, $type) = explode(':', $bundle);
    if ($entity != 'crm_core_contact') {
      return FALSE;
    }
  }
  return TRUE;
}

/**
 * Return a list of relation bundle that are crm_core_relationship
 *
 * @return array $relationships
 * an array of relation bundle of relationships keyed by relationship type
 */
function crm_core_relationship_get_relationships() {
  $relationships = array();
  foreach (RelationType::loadMultiple() as $type => $info) {
    if (crm_core_relationship_is_relationship_type($type)) {
      $relationships[$type] = $info;
    }
  }
  return $relationships;
}

/**
 * Create new relation object.
 *   Wrapper for controller.
 *
 * @param array $values
 *   Keyed array of new object attribures.
 *
 * @return object relation entity
 *
 * @see entity_create()
 */
function crm_core_relation_create($values) {
  return new Entity($values, 'relation');
}

/**
 * Implements hook_field_attach_create_bundle.
 */
function crm_core_relationship_field_attach_create_bundle($relation_type, $relation_bundle) {
  if (crm_core_relationship_is_relationship_type($relation_bundle)) {
    module_load_include('inc', 'crm_core_relationship', 'crm_core_relationship.fields');
    $fields = _crm_core_relationship_field_default_fields();

    // Create the fields if they don't exist
    foreach ($fields as $field) {
      $info = field_info_field($field['field_name']);
      if (empty($info)) {
        field_create_field($field);
      }
    }
    $field_instances = _crm_core_relationship_field_status_instance($relation_bundle);

    // Create field instances if they don't exist
    foreach ($field_instances as $instance) {
      $info_instance = field_info_instance('relation', $instance['field_name'], $relation_bundle);
      if (empty($info_instance)) {
        field_create_instance($instance);
      }
    }
  }
}

/**
 * Implements hook_theme().
 */
function crm_core_relationship_theme($existing, $type, $theme, $path) {
  return array(
    'relationship' => array(
      'render element' => 'elements',
      'template' => 'relationship',
      'path' => $path . '/templates',
    ),
  );
}

/**
 * Implements hook_preprocess().
 */
function crm_core_relationship_preprocess_relationship(&$variables) {
  $variables['view_mode'] = $variables['elements']['#view_mode'];
  $variables['relationship'] = $variables['elements']['#relationship'];
  $variables['language'] = $variables['elements']['#view_mode'];
  $variables['content'] = relation_view($variables['relationship'], $variables['view_mode']);
  $entity = $variables['relationship'];

  // add classes based on the type of relation
  $variables['classes_array'][] = 'relation';
  $variables['classes_array'][] = 'relation-' . $entity->relation_type;
}

/**
 * Implements hook_theme_suggestions_HOOK().
 */
function crm_core_relationship_theme_suggestions_relationship(array $variables) {
  $suggestions = array();
  $entity = $variables['relationship'];

  // Add template suggestions.
  $suggestions[] = 'relationship__' . $entity->relation_type;
  $suggestions[] = 'relationship__' . $entity
    ->id();
  return $suggestions;
}

/**
 * Page callback to override relation view page.
 *
 * @param $relationship
 *  Relationship object.
 *
 * @return string
 *  Rendered HTML.
 */
function crm_core_relationship_view_relationship($relationship) {
  $langcode = $GLOBALS['language_content']->language;
  return array(
    '#theme' => 'relationship',
    '#relationship' => $relationship,
    '#view_mode' => 'full',
    '#language' => $langcode,
  );
}

Functions

Namesort descending Description
crm_core_relationship_access_permissions Access callback for all relationship permissions
crm_core_relationship_crm_core_contact_delete Implements hook crm_core_contact_delete
crm_core_relationship_field_attach_create_bundle Implements hook_field_attach_create_bundle.
crm_core_relationship_get_relationships Return a list of relation bundle that are crm_core_relationship
crm_core_relationship_is_contact_bundles Return true if there is only CRM contacts in relation type bundles.
crm_core_relationship_is_relationship_type Check if relation_type is CRM relationship_type.
crm_core_relationship_load_contact_types Return contact types available for specific relationship type.
crm_core_relationship_load_relationship_types Return relationship types that can be applied to specific contact type.
crm_core_relationship_permission Implements hook_permission().
crm_core_relationship_preprocess_relationship Implements hook_preprocess().
crm_core_relationship_theme Implements hook_theme().
crm_core_relationship_theme_suggestions_relationship Implements hook_theme_suggestions_HOOK().
crm_core_relationship_view_relationship Page callback to override relation view page.
crm_core_relation_create Create new relation object. Wrapper for controller.