You are here

crm_core_relationship.module in CRM Core 8

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.

@TODO: Unported.

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.
 *
 * @TODO: Unported.
 */
use Drupal\crm_core_contact\Entity\ContactType;
use Drupal\collect\Entity\RelationType;

//@codingStandardsIgnoreFile

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

  // Administration permission.
  $permissions['administer contact relationship types'] = [
    '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'] = [
    'title' => t('Create Any Contact Relationships'),
    'description' => t('Allows user to create any CRM relationship.'),
  ];
  $permissions['view relation entities of any contact relationship'] = [
    'title' => t('View Any Contact Relationships'),
    'description' => t('Allows user to view any CRM relationship'),
  ];
  $permissions['edit relation entities of any contact relationship'] = [
    '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 = [
    'permission labels' => [
      '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 [];
  }
  $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 = [];
  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 mixed $contact_type
 *   CRM contact type name.
 * @param mixed $reverse
 *   Whether relationship is reversed.
 */
function crm_core_relationship_load_relationship_types($contact_type, $reverse = 0) {
  $relation_types = RelationType::loadMultiple();
  $available_relationship_types = [];
  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 = [];
  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
 *   an array of relation bundle of relationships keyed by relationship type
 */
function crm_core_relationship_get_relationships() {
  $relationships = [];
  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 [
    'relationship' => [
      '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 = [];
  $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 [
    '#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.