View source
<?php
define('REDHEN_RELATION_STATUS_FIELD', 'redhen_relation_status');
define('REDHEN_RELATION_ROLES_FIELD', 'redhen_relation_roles');
define('REDHEN_RELATION_AFFILIATION', 'redhen_affiliation');
define('REDHEN_RELATION_CONNECTION', 'redhen_connection');
function redhen_relation_menu() {
$items = array();
$items['redhen/contact/%redhen_contact/connections'] = array(
'title' => 'Connections',
'page callback' => 'redhen_relation_connections_page',
'page arguments' => array(
2,
'redhen_contact',
),
'access callback' => 'redhen_relation_access',
'access arguments' => array(
'view',
2,
),
'type' => MENU_LOCAL_TASK,
'weight' => -5,
);
$items['redhen/contact/%redhen_contact/connections/add'] = array(
'title' => 'Add Connection',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'redhen_relation_connection_form',
2,
),
'file' => 'includes/redhen_relation.forms.inc',
'access callback' => 'redhen_relation_access',
'access arguments' => array(
'edit',
2,
),
'type' => MENU_LOCAL_ACTION,
);
$items['redhen/contact/%redhen_contact/connections/%relation/edit'] = array(
'title' => 'Edit Connection',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'redhen_relation_connection_form',
2,
4,
),
'file' => 'includes/redhen_relation.forms.inc',
'access callback' => 'redhen_relation_entity_access',
'access arguments' => array(
'update',
4,
),
'type' => MENU_LOCAL_ACTION,
);
$items['redhen/org/%redhen_org/connections'] = array(
'title' => 'Connections',
'page callback' => 'redhen_relation_connections_page',
'page arguments' => array(
2,
'redhen_org',
),
'access callback' => 'redhen_relation_access',
'access arguments' => array(
'view',
2,
),
'type' => MENU_LOCAL_TASK,
'weight' => -5,
);
$items['redhen/org/%redhen_org/connections/add'] = array(
'title' => 'Add Connection',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'redhen_relation_connection_form',
2,
),
'file' => 'includes/redhen_relation.forms.inc',
'access callback' => 'redhen_relation_access',
'access arguments' => array(
'edit',
2,
),
'type' => MENU_LOCAL_ACTION,
);
$items['redhen/relation/autocomplete/%'] = array(
'title' => 'Autocomplete for RedHen Relations',
'page callback' => 'redhen_relation_autocomplete',
'page arguments' => array(
3,
4,
5,
6,
7,
),
'access callback' => TRUE,
'type' => MENU_CALLBACK,
);
return $items;
}
function redhen_relation_menu_alter(&$items) {
$items['relation/%relation']['title callback'] = 'redhen_relation_page_title';
$items['relation/%relation']['access callback'] = 'redhen_relation_entity_access';
$items['relation/%relation']['access arguments'] = array(
'view',
1,
);
$items['relation/%relation/edit']['access callback'] = 'redhen_relation_entity_access';
$items['relation/%relation/edit']['access arguments'] = array(
'update',
1,
);
$items['relation/%relation/delete']['access callback'] = 'redhen_relation_entity_access';
$items['relation/%relation/delete']['access arguments'] = array(
'delete',
1,
);
}
function redhen_relation_entity_access($op, $entity) {
global $user;
if (user_access('administer relations')) {
return TRUE;
}
$permission = FALSE;
switch ($op) {
case 'view':
$permission = 'access relations';
$relation_permission = 'view_relation';
break;
case 'create':
$permission = 'create relations';
$relation_permission = 'edit_relation';
break;
case 'update':
$relation_permission = 'edit_relation';
$permission = 'edit relations';
break;
case 'delete':
$relation_permission = 'delete_relation';
$permission = 'delete relations';
break;
}
$user_access = user_access($permission);
if (array_key_exists('relation_type', $entity) && $entity->relation_type == REDHEN_RELATION_AFFILIATION) {
$permissions = redhen_relation_role_get_permissions($user);
$relation = relation_get_endpoints($entity, 'redhen_org');
$org = $relation ? current(current($relation)) : array();
if ($relation && isset($permissions[$org->org_id][$relation_permission]) && $permissions[$org->org_id][$relation_permission] !== 0) {
$user_access = TRUE;
}
}
return $user_access;
}
function redhen_relation_page_title($relation) {
$endpoints = field_get_items('relation', $relation, 'endpoints');
$redhen_entities = array(
'redhen_contact',
'redhen_org',
);
if (!in_array($endpoints[0]['entity_type'], $redhen_entities) || !in_array($endpoints[1]['entity_type'], $redhen_entities)) {
return relation_ui_page_title($relation);
}
$relation_type = relation_type_load($relation->relation_type);
foreach ($endpoints as $endpoint) {
if ($endpoint['r_index'] == 0) {
$label1 = entity_load_single($endpoint['entity_type'], $endpoint['entity_id'])
->label();
}
if ($endpoint['r_index'] == 1) {
$label2 = entity_load_single($endpoint['entity_type'], $endpoint['entity_id'])
->label();
}
}
return t('@type between @label1 and @label2', array(
'@type' => relation_get_type_label($relation_type),
'@label1' => $label1,
'@label2' => $label2,
));
}
function redhen_relation_permission() {
return array(
'view redhen org connections' => array(
'title' => t('Access RedHen Org Connections'),
'description' => t('View the connections for an organization.'),
),
'view redhen contact connections' => array(
'title' => t('Access RedHen Contact Connections'),
'description' => t('View the connections for a contact.'),
),
'edit redhen org connections' => array(
'title' => t('Manage RedHen Org Connections'),
'description' => t('Add and edit connections for an organization.'),
),
'edit redhen contact connections' => array(
'title' => t('Manage RedHen Contact Connections'),
'description' => t('Add and edit connections for a contact.'),
),
'delete redhen org connections' => array(
'title' => t('Delete RedHen Org Connections'),
'description' => t('Delete connections for an organization.'),
),
'delete redhen contact connections' => array(
'title' => t('Delete RedHen Contact Connections'),
'description' => t('Delete connections for a contact.'),
),
'administer relation roles' => array(
'title' => t('Administer redhen relation roles'),
'description' => t('Administer redhen relation roles.'),
),
);
}
function redhen_relation_access($op, $entity = NULL, $account = NULL, $entity_type = NULL) {
global $user;
$account = isset($account) ? $account : $user;
$permissions = redhen_relation_role_get_permissions($account);
$entity_type = $entity_type ? $entity_type : $entity
->entityType();
$type = $entity_type == 'redhen_contact' ? 'contact' : 'org';
if (entity_access($op, $entity_type, $entity) && user_access("{$op} redhen {$type} connections")) {
return TRUE;
}
if (($op == 'edit' || $op == 'view') && $entity_type == 'redhen_org' && isset($permissions[$entity->org_id]) && $permissions[$entity->org_id]['add_connection'] !== 0) {
return TRUE;
}
return FALSE;
}
function redhen_relation_role_access($op, $entity = NULL, $account = NULL, $entity_type = NULL) {
if ($op == 'view') {
return TRUE;
}
else {
return user_access('administer relation roles', $account);
}
}
function redhen_relation_role_get_permissions($account) {
$return =& drupal_static(__FUNCTION__);
if (!isset($return[$account->uid])) {
$return_permissions = array();
$contact = redhen_contact_load_by_user($account);
if ($contact) {
$related = redhen_relation_relations($contact, REDHEN_RELATION_AFFILIATION, TRUE);
$relations = relation_load_multiple(array_keys($related));
foreach ($relations as $relation_id => $relation) {
$relation_wrapper = entity_metadata_wrapper('relation', $relation);
$redhen_relation_roles = $relation_wrapper->redhen_relation_roles
->value();
foreach ($redhen_relation_roles as $redhen_relation_role) {
if ($redhen_relation_role) {
$redhen_relation_role_wrapper = entity_metadata_wrapper('redhen_relation_role', $redhen_relation_role);
$org_id = $related[$relation_id][0]->org_id;
$permissions = $redhen_relation_role_wrapper->permissions
->value();
foreach ($permissions as $permission => $value) {
if ($value) {
$return_permissions[$org_id][$permission] = $value;
}
}
}
}
}
}
$return[$account->uid] = $return_permissions;
}
return $return[$account->uid];
}
function redhen_relation_connections_page($entity) {
$related = redhen_relation_relations($entity);
if (!empty($related)) {
$header = array(
'connection' => t('Connection'),
'type' => t('Type'),
'name' => t('Name'),
'role' => t('Roles'),
'status' => t('Status'),
'created' => t('Created'),
'author' => t('Author'),
);
if ($entity
->entityType() == 'redhen_org') {
$header['primary'] = t('Primary contact');
}
$header['operations'] = array(
'data' => t('Operations'),
);
$destination = drupal_get_destination();
foreach ($related as $relation_id => $related_entities) {
$relation = relation_load($relation_id);
$relation_wrapper = entity_metadata_wrapper('relation', $relation);
$relation_uri = entity_uri('relation', $relation);
$reversed = FALSE;
$endpoints = field_get_items('relation', $relation, 'endpoints');
foreach ($endpoints as $endpoint) {
if ($endpoint['entity_type'] == $entity
->entityType() && $endpoint['r_index']) {
$reversed = TRUE;
break;
}
}
foreach ($related_entities as $related_entity) {
$object_label = entity_label($related_entity
->entityType(), $related_entity);
$object_uri = entity_uri($related_entity
->entityType(), $related_entity);
$author = user_load($relation->uid);
if (strpos($relation->relation_type, 'redhen_') === FALSE) {
$active = t('NA', array(), array(
'context' => 'redhen_relation',
));
}
else {
$items = field_get_items('relation', $relation, REDHEN_RELATION_STATUS_FIELD);
$active = $items[0]['value'] ? t('Active', array(), array(
'context' => 'redhen_relation',
)) : t('Inactive', array(), array(
'context' => 'redhen_relation',
));
}
$related_entity_info = entity_get_info($related_entity
->entityType());
$relation_role_names = array();
if (isset($relation_wrapper->{REDHEN_RELATION_ROLES_FIELD})) {
$relation_roles = $relation_wrapper->{REDHEN_RELATION_ROLES_FIELD}
->value();
foreach ($relation_roles as $relation_role) {
if (!empty($relation_role)) {
$relation_role_names[] = $relation_role
->label();
}
}
sort($relation_role_names);
}
$relation_role_names = implode(', ', $relation_role_names);
$data = array(
'connection' => array(
'data' => array(
'#markup' => relation_get_type_label($relation, $reversed),
),
),
'type' => $related_entity_info['label'],
'name' => array(
'data' => array(
'#type' => 'link',
'#title' => $object_label,
'#href' => $object_uri['path'],
),
),
'role' => $relation_role_names,
'active' => $active,
'created' => date('m/d/Y', $relation->created),
'author' => $author->name,
);
$row_classes = array();
if ($entity
->entityType() == 'redhen_org' && $related_entity
->entityType() == 'redhen_contact') {
if ($entity->primary_contact_id !== $related_entity->contact_id) {
$entity_uri = entity_uri('redhen_org', $entity);
$data['primary'] = array(
'data' => array(
'#type' => 'link',
'#title' => t('set as primary'),
'#href' => $entity_uri['path'] . '/primary/' . $related_entity->contact_id,
'#options' => array(
'query' => array(
$destination,
),
),
),
);
}
else {
$data['primary'] = t('Primary');
$row_classes[] = 'primary_contact';
}
}
elseif ($entity
->entityType() == 'redhen_org') {
$data[] = t('NA', array(), array(
'context' => 'redhen_relation',
));
}
$ops = array();
if (redhen_relation_entity_access('view', $relation)) {
$ops['view'] = array(
'title' => t('view'),
'href' => $relation_uri['path'],
);
}
if (redhen_relation_entity_access('update', $relation)) {
$ops['edit'] = array(
'title' => t('edit'),
'href' => $relation_uri['path'] . '/edit',
'query' => $destination,
);
}
if (redhen_relation_entity_access('delete', $relation)) {
$ops['delete'] = array(
'title' => t('delete'),
'href' => $relation_uri['path'] . '/delete',
'query' => $destination,
);
}
if (count($ops) > 1) {
$data['operations'] = array(
'data' => array(
'#theme' => 'links__node_operations',
'#links' => $ops,
'#attributes' => array(
'class' => array(
'links',
'inline',
),
),
),
);
}
elseif (!empty($ops)) {
$link = reset($ops);
$data['operations'] = array(
'data' => array(
'#type' => 'link',
'#title' => $link['title'],
'#href' => $link['href'],
'#options' => isset($link['query']) ? array(
'query' => $link['query'],
) : array(),
),
);
}
else {
unset($header['operations']);
}
$rows[$relation_id] = array(
'data' => $data,
'class' => $row_classes,
);
}
}
return array(
'#theme' => 'table',
'#header' => $header,
'#rows' => $rows,
);
}
else {
return t('%name has no connections.', array(
'%name' => $entity
->label(),
));
}
}
function redhen_relation_relations($entity, $relation_types = array(), $active = FALSE) {
if ($relation_types && !is_array($relation_types)) {
$relation_types = array(
$relation_types,
);
}
$related_entities =& drupal_static(__FUNCTION__ . $entity
->entityType() . $entity
->internalIdentifier() . implode('-', $relation_types) . $active, array());
if ($related_entities) {
return $related_entities;
}
$query = relation_query($entity
->entityType(), $entity
->internalIdentifier());
if ($relation_types) {
$query
->propertyCondition('relation_type', $relation_types, 'IN');
}
if ($active) {
$query
->fieldCondition(REDHEN_RELATION_STATUS_FIELD, 'value', TRUE);
}
$query
->addMetaData('account', user_load(1));
$query
->addTag('redhen_relation');
$results = $query
->execute();
if ($results) {
$relations = relation_load_multiple(array_keys($results));
foreach ($relations as $relation) {
$rid = entity_id('relation', $relation);
$related_entities[$rid] = array();
$duplicate = FALSE;
$endpoints = field_get_items('relation', $relation, 'endpoints');
foreach ($endpoints as $endpoint) {
if ($relation->arity > 1 && $endpoint['entity_type'] == $entity
->entityType() && $endpoint['entity_id'] == $entity
->internalIdentifier() && $duplicate == FALSE) {
$duplicate = TRUE;
}
else {
$object_entities = entity_load($endpoint['entity_type'], array(
$endpoint['entity_id'],
));
$related_entities[$rid][] = reset($object_entities);
}
}
}
}
return $related_entities;
}
function redhen_relation_get_available_entities($entity, $entity_type_to_relate, $relation_type, $search = '', $limit = 0) {
$entities = array();
if (!in_array($entity_type_to_relate, array(
'redhen_contact',
'redhen_org',
))) {
return $entities;
}
$query = new EntityFieldQuery();
$query
->entityCondition('entity_type', $entity_type_to_relate)
->propertyCondition('redhen_state', REDHEN_STATE_ACTIVE);
$existing = redhen_relation_relations($entity, $relation_type);
if (!empty($existing)) {
$info = entity_get_info($entity_type_to_relate);
$id_key = $info['entity keys']['id'];
$to_exclude = array();
foreach ($existing as $relation_id => $related_entities) {
foreach ($related_entities as $related_entity) {
$to_exclude[] = entity_id($related_entity
->entityType(), $related_entity);
}
}
$query
->propertyCondition($id_key, $to_exclude, 'NOT IN');
}
if ($search != '') {
if ($entity_type_to_relate == 'redhen_contact') {
$query
->addTag('redhen_contact_label');
}
$query
->propertyCondition('label', $search, 'CONTAINS');
}
if ($limit > 0) {
$query
->range(0, $limit);
}
if ($result = $query
->execute()) {
$entities = entity_load($entity_type_to_relate, array_keys($result[$entity_type_to_relate]));
}
return $entities;
}
function redhen_relation_autocomplete($relation_type = '', $entity_type_to_relate = '', $entity_type = '', $entity_id = '', $search = '') {
$options = array();
if (!empty($relation_type) && !empty($entity_type_to_relate) && !empty($entity_type) && !empty($entity_id)) {
$entity = entity_load_single($entity_type, $entity_id);
$available_entities = redhen_relation_get_available_entities($entity, $entity_type_to_relate, $relation_type, $search, 10);
foreach ($available_entities as $available_entity) {
$entity_id = $available_entity
->internalIdentifier();
$entity_label = $available_entity
->label();
$options[check_plain($entity_label) . ' (' . $entity_id . ')'] = check_plain($entity_label);
}
}
drupal_json_output($options);
}
function redhen_relation_entity_update($entity, $entity_type) {
if ($entity_type == 'redhen_contact' || $entity_type == 'redhen_org') {
if ($entity->redhen_state != REDHEN_STATE_ACTIVE) {
$query = relation_query($entity_type, $entity
->internalIdentifier());
$query
->addMetaData('account', user_load(1));
$query
->addTag('redhen_relation');
$results = $query
->execute();
if ($results) {
$relations = relation_load_multiple(array_keys($results));
foreach ($relations as $relation) {
$relation->{REDHEN_RELATION_STATUS_FIELD}[LANGUAGE_NONE][0]['value'] = 0;
relation_save($relation);
}
}
}
}
}
function redhen_relation_entity_info() {
$entities = array(
'redhen_relation_role' => array(
'label' => t('RedHen Relation Role'),
'plural label' => t('RedHen Relation Roles'),
'controller class' => 'RedhenRelationRoleEntityController',
'entity class' => 'RedhenRelationRole',
'base table' => 'redhen_relation_role',
'fieldable' => FALSE,
'entity keys' => array(
'id' => 'redhen_relation_role_id',
'label' => 'label',
'name' => 'name',
),
'bundles' => array(
'redhen_relation_role' => array(
'label' => 'RedHen Relation Role',
),
),
'admin ui' => array(
'path' => 'admin/structure/redhen/relation_roles',
'file' => 'redhen_relation_role.forms.inc',
'file path' => drupal_get_path('module', 'redhen_relation') . '/includes',
'controller class' => 'RedhenRelationRoleUIController',
),
'token type' => 'redhen_relation_role',
'module' => 'redhen_relation',
'access callback' => 'redhen_relation_role_access',
'exportable' => TRUE,
),
);
return $entities;
}
function redhen_relation_entity_info_alter(&$entity_info) {
$entity_info['relation']['view modes']['teaser'] = array(
'label' => t('Teaser'),
'custom settings' => TRUE,
);
$entity_info['relation']['access callback'] = 'redhen_relation_entity_access';
}
function redhen_relation_views_api() {
return array(
'api' => 3,
'path' => drupal_get_path('module', 'redhen_relation') . '/includes/views',
);
}
function redhen_relation_get_available_types($entity_type, $bundle) {
$relation_types = relation_get_available_types($entity_type, $bundle, 'both');
foreach ($relation_types as $key => $relation_type) {
$redhen_types = array(
'redhen_contact',
'redhen_org',
);
foreach ($relation_type->source_bundles as $source_bundle) {
list($source_entity_type) = explode(':', $source_bundle);
if (!in_array($source_entity_type, $redhen_types)) {
unset($relation_types[$key]);
break;
}
}
foreach ($relation_type->target_bundles as $target_bundle) {
list($target_entity_type) = explode(':', $target_bundle);
if (!in_array($target_entity_type, $redhen_types)) {
unset($relation_types[$key]);
break;
}
}
}
return $relation_types;
}
function redhen_relation_role_name_exists($name, $element, &$form_state) {
$relation_role = entity_load('redhen_relation_role', array(
$name,
));
$relation_role = current($relation_role);
if ($relation_role && $relation_role->redhen_relation_role_id != $form_state['redhen_relation_role']->redhen_relation_role_id) {
return TRUE;
}
}
function redhen_relation_role_permissions() {
$roles = module_invoke_all('redhen_relation_role_permissions');
return $roles;
}
function redhen_relation_redhen_relation_role_permissions() {
$roles = array(
'add_connection' => array(
'label' => 'Add Connection',
),
'view_relation' => array(
'label' => 'View Relation',
),
'edit_relation' => array(
'label' => 'Edit Relation',
),
'delete_relation' => array(
'label' => 'Delete Relation',
),
);
return $roles;
}