user_relationships_ui.module in User Relationships 7
Same filename and directory in other branches
UI components of user_relationships @author Jeff Smick (creator) @author Alex Karshakevich (maintainer) http://drupal.org/user/183217 @author Darren Ferguson (contributor) http://drupal.org/user/70179
File
user_relationships_ui/user_relationships_ui.moduleView source
<?php
/**
* @file
* UI components of user_relationships
* @author Jeff Smick (creator)
* @author Alex Karshakevich (maintainer) http://drupal.org/user/183217
* @author Darren Ferguson (contributor) http://drupal.org/user/70179
*/
define('USER_RELATIONSHIPS_UI_PATH', drupal_get_path('module', 'user_relationships_ui'));
/*
* Notify the user of pending relationship requests
*/
function _user_relationships_ui_set_notifications(&$account) {
global $user;
//only do this for the active user
if ($account->uid != $user->uid) {
return;
}
$notifications = drupal_get_messages('status', FALSE);
$notifications = isset($notifications['status']) ? $notifications['status'] : array();
$relationships = user_relationships_load(array(
'requestee_id' => $account->uid,
'approved' => FALSE,
));
foreach ($relationships as $relationship) {
$msg = user_relationships_get_message('pending', $relationship, array(
'!pending_relationship_requests' => l(t('pending relationship requests'), variable_get('user_relationships_requests_link', 'relationships/received')),
));
if (!in_array($msg, $notifications)) {
drupal_set_message($msg);
}
}
}
/**
* List of possible relationship actions with between two users.
*
* @param $viewer
* User object for the visitor.
* @param $viewed
* User object for the user being looked at.
* @param action_types
* Associative array of kinds of links to show (all by default).
* Only the existence of specific array keys is needed: add, remove,
* requested, received.
* @param $rtids
* Associative array of relationships type ids to show (all by default).
* Row values must be rtids of relationship types.
*
* @return
* An array with actions as strings.
*/
function user_relationships_ui_actions_between($viewer, $viewed, $action_types = array(
'add' => 1,
'remove' => 1,
'requested' => 1,
'received' => 1,
), $rtids = array()) {
if ($viewer->uid == $viewed->uid) {
return array();
}
$list = array();
$from_us = user_relationships_load(array(
'requester_id' => $viewer->uid,
'requestee_id' => $viewed->uid,
));
if (isset($action_types['requested'])) {
foreach ($from_us as $relationship) {
if (!$relationship->approved && (empty($rtids) || in_array($relationship->rtid, $rtids))) {
$list[] = t('You have sent a new @rel_name request to this user. (!pending_requests)', array(
'!pending_requests' => l(t('pending requests'), "relationships/sent"),
) + user_relationships_type_translations($relationship));
}
}
}
if (isset($action_types['received'])) {
$to_us = user_relationships_load(array(
'requester_id' => $viewed->uid,
'requestee_id' => $viewer->uid,
));
foreach ($to_us as $relationship) {
if (!$relationship->approved && (empty($rtids) || in_array($relationship->rtid, $rtids)) && user_relationships_user_access('maintain @relationship relationships', $relationship)) {
$list[] = t('This user has requested to be your @rel_name. (!pending_requests)', array(
'!pending_requests' => l(t('pending requests'), "user/{$viewer->uid}/relationships/received"),
) + user_relationships_type_translations($relationship));
}
}
}
if (isset($action_types['add'])) {
$relationships = user_relationships_get_requestable_rtypes($viewer, $viewed, 'full');
if ($relationships) {
// If configured, create direct links.
if (variable_get('user_relationships_show_direct_links', 1)) {
// Create a single link, or one for each relationship type.
foreach ($relationships as $relationship_type) {
if (empty($rtids) || in_array($relationship_type->rtid, $rtids)) {
$list[] = theme('user_relationships_request_relationship_direct_link', array(
'relate_to' => $viewed,
'relationship_type' => $relationship_type,
));
}
}
}
else {
$list[] = theme('user_relationships_request_relationship_link', array(
'relate_to' => $viewed,
));
}
}
}
if (isset($action_types['remove'])) {
foreach ($from_us as $relationship) {
if ($relationship->approved && (empty($rtids) || in_array($relationship->rtid, $rtids)) && !isset($list[$relationship->rid]) && user_relationships_ui_check_access('view', NULL, $relationship)) {
if (user_relationships_ui_check_access('delete', NULL, $relationship)) {
$list[] = t('@rel_name (!remove_link)', array(
'@rel_name' => user_relationships_type_get_name($relationship) . ($relationship->is_oneway ? $relationship->requester_id == $viewer->uid ? t(' (You to Them)') : t(' (Them to You)') : NULL),
'!remove_link' => theme('user_relationships_remove_link', array(
'uid' => $viewer->uid,
'rid' => $relationship->rid,
)),
));
}
else {
$list[] = user_relationships_type_get_name($relationship) . ($relationship->is_oneway ? $relationship->requester_id == $viewer->uid ? t(' (You to Them)') : t(' (Them to You)') : NULL);
}
}
}
}
return $list;
}
/**********************************
* CALLBACKS
**********************************/
/**
* Check access callback
*/
function user_relationships_ui_check_access($type, $account = NULL, $relationship_type = NULL) {
global $user;
if (!is_object($account)) {
$account = $user;
}
if (!is_object($relationship_type)) {
$relationship_type = user_relationships_type_load($relationship_type);
}
if (user_access('administer user relationships')) {
return TRUE;
}
// If the user does not any have permission, deny access.
if (!user_relationships_can_receive($account)) {
return FALSE;
}
switch ($type) {
case 'view':
// First check if it is the current user and if he has view own
// permission.
if ($account->uid == $user->uid && user_relationships_user_access('view own @relationship relationships', $relationship_type)) {
return TRUE;
}
// If this is a different user or he doesn't have that permission,
// check the view all permission.
if (user_relationships_user_access('view all @relationship relationships', $relationship_type)) {
return TRUE;
}
break;
case 'approve':
// Only the administer permission allows to approve, request, delete
// relationships for other users, which was already checked.
if ($account->uid == $user->uid && user_relationships_user_access('maintain @relationship relationships', $relationship_type)) {
return TRUE;
}
break;
case 'request':
if ($account->uid == $user->uid && user_relationships_can_request($account, $relationship_type)) {
return TRUE;
}
break;
case 'delete':
// Do not allow access if this is a oneway relationship requested by another user.
if (is_object($relationship_type) && $relationship_type->is_oneway && $relationship_type->requester_id != $user->uid) {
return FALSE;
}
if ($account->uid == $user->uid && user_relationships_user_access('delete @relationship relationships', $relationship_type)) {
return TRUE;
}
break;
}
return FALSE;
}
/**********************************
*
* HOOKS
*
**********************************/
/**
* Implements hook_help().
*/
function user_relationships_ui_help($section) {
switch ($section) {
case 'admin/help#user_relationships_ui':
$output = '<p>' . t('This module allows you to create relationship types that users can use to connect to each other.') . '</p>';
return $output;
case 'admin/config/people/relationships':
$output = '<p>' . t('This page lets you setup user relationship types.') . '</p>';
return $output;
}
}
/**
* Implements hook_init().
*/
function user_relationships_ui_init() {
//do not enable ajax functions if set in admin/config/people/relationships/settings
if (!variable_get('user_relationships_enable_ajax_popups', 0)) {
return;
}
drupal_add_js(USER_RELATIONSHIPS_UI_PATH . '/user_relationships_ui.js');
drupal_add_css(USER_RELATIONSHIPS_UI_PATH . '/user_relationships_ui.css');
$settings['user_relationships_ui']['loadingimage'] = file_create_url(USER_RELATIONSHIPS_UI_PATH . '/images/loadingAnimation.gif');
$settings['user_relationships_ui']['savingimage'] = file_create_url(USER_RELATIONSHIPS_UI_PATH . '/images/savingimage.gif');
$settings['user_relationships_ui']['position'] = array(
'position' => variable_get('user_relationships_position', 'absolute'),
'left' => variable_get('user_relationships_left', '0'),
'top' => variable_get('user_relationships_top', '0'),
);
drupal_add_js($settings, 'setting');
}
/**
* Implements hook_perm().
*/
function user_relationships_ui_permission() {
$permissions = array();
foreach (user_relationships_types_load() as $type) {
$permissions['view own ' . $type->machine_name . ' relationships'] = array(
'title' => t('View own %name relationships', array(
'%name' => $type->name,
)),
'description' => t('The user is allowed to see his own relationships of this type.'),
);
$permissions['view all ' . $type->machine_name . ' relationships'] = array(
'title' => t('View all %name relationships', array(
'%name' => $type->name,
)),
'description' => t('The user is allowed to see all relationships of this type.'),
);
}
return $permissions;
}
/**
* Implements hook_footer().
*/
function user_relationships_ui_page_alter(&$page) {
// This is the div we are utilizing for the form popups for confirmation.
$page['page_bottom']['user_relationships'] = array(
'#markup' => '<div id="user_relationships_popup_form" class="user_relationships_ui_popup_form"></div>',
);
}
/**
* Implements hook_menu().
*/
function user_relationships_ui_menu() {
$items['relationships'] = array(
'title' => 'My relationships',
'type' => MENU_NORMAL_ITEM,
'access callback' => 'user_relationships_ui_check_access',
'access arguments' => array(
'view',
),
'page callback' => 'user_relationships_page',
'file' => 'user_relationships_ui.pages.inc',
'menu_name' => 'user-menu',
);
$items['relationships/list'] = array(
'title' => 'Current',
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => -10,
'access callback' => 'user_relationships_ui_check_access',
'access arguments' => array(
'view',
),
'menu_name' => 'user-menu',
);
$items['relationships/received'] = array(
'title' => 'Received requests',
'title callback' => 'user_relationships_ui_title_callback_pending',
'title arguments' => array(
'requestee_id',
),
'access callback' => 'user_relationships_ui_check_access',
'access arguments' => array(
'approve',
),
'type' => MENU_LOCAL_TASK,
'weight' => -9,
'page callback' => 'user_relationships_pending_requests_page',
'page arguments' => array(
'requestee_id',
),
'file' => 'user_relationships_ui.pages.inc',
'menu_name' => 'user-menu',
);
$items['relationships/sent'] = array(
'title' => 'Sent requests',
'title callback' => 'user_relationships_ui_title_callback_pending',
'title arguments' => array(
'requester_id',
),
'access callback' => 'user_relationships_ui_check_access',
'access arguments' => array(
'request',
),
'type' => MENU_LOCAL_TASK,
'weight' => -8,
'page callback' => 'user_relationships_pending_requests_page',
'page arguments' => array(
'requester_id',
),
'file' => 'user_relationships_ui.pages.inc',
'menu_name' => 'user-menu',
);
$show_tabs = db_query('SELECT rtid, show_tab FROM {user_relationships_ui_settings} WHERE show_tab = 1')
->fetchAllKeyed();
foreach (user_relationships_types_load() as $rtid => $relationship) {
if (isset($show_tabs[$rtid])) {
$items["relationships/{$rtid}"] = array(
'title' => $relationship->rtid,
'title callback' => 'user_relationships_ui_title_callback',
'type' => MENU_LOCAL_TASK,
'access callback' => 'user_relationships_ui_check_access',
'access arguments' => array(
'view',
NULL,
1,
),
'page callback' => 'user_relationships_page',
'page arguments' => array(
NULL,
1,
),
'file' => 'user_relationships_ui.pages.inc',
'menu_name' => 'user-menu',
);
}
}
$items['relationships/%user_relationships/remove'] = array(
'title' => 'Remove relationship',
'type' => MENU_CALLBACK,
'access callback' => 'user_relationships_ui_check_access',
'access arguments' => array(
'delete',
),
'page callback' => 'drupal_get_form',
'page arguments' => array(
'user_relationships_ui_remove',
1,
),
'file' => 'user_relationships_ui.forms.inc',
);
$items['relationship/%user/request'] = array(
'title' => 'Create a relationship',
'type' => MENU_CALLBACK,
'access callback' => 'user_relationships_ui_check_access',
'access arguments' => array(
'request',
),
'page callback' => 'user_relationships_ui_request_ajax',
'page arguments' => array(
1,
),
'file' => 'user_relationships_ui.forms.inc',
);
$items['user/%user/relationships'] = array(
'title' => 'Relationships',
'access callback' => 'user_relationships_ui_check_access',
'access arguments' => array(
'view',
1,
),
'page callback' => 'user_relationships_page',
'page arguments' => array(
1,
),
'file' => 'user_relationships_ui.pages.inc',
'type' => MENU_LOCAL_TASK,
);
$items['user/%user/relationships/list'] = array(
'title' => 'Current',
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => -10,
'access callback' => 'user_relationships_ui_check_access',
'access arguments' => array(
'view',
1,
),
);
$items['user/%user/relationships/received'] = array(
'title' => 'Received requests',
'title callback' => 'user_relationships_ui_title_callback_pending',
'title arguments' => array(
'requestee_id',
1,
),
'access callback' => 'user_relationships_ui_check_access',
'access arguments' => array(
'approve',
1,
),
'type' => MENU_LOCAL_TASK,
'weight' => -9,
'page callback' => 'user_relationships_pending_requests_page',
'page arguments' => array(
'requestee_id',
1,
),
'file' => 'user_relationships_ui.pages.inc',
);
$items['user/%user/relationships/sent'] = array(
'title' => 'Sent requests',
'title callback' => 'user_relationships_ui_title_callback_pending',
'title arguments' => array(
'requester_id',
1,
),
'access callback' => 'user_relationships_ui_check_access',
'access arguments' => array(
'request',
1,
),
'type' => MENU_LOCAL_TASK,
'weight' => -8,
'page callback' => 'user_relationships_pending_requests_page',
'page arguments' => array(
'requester_id',
1,
),
'file' => 'user_relationships_ui.pages.inc',
);
foreach (user_relationships_types_load() as $rtid => $relationship) {
$items["user/%user/relationships/{$rtid}"] = array(
'title' => $relationship->rtid,
'title callback' => 'user_relationships_ui_title_callback',
'type' => MENU_LOCAL_TASK,
'access callback' => 'user_relationships_ui_check_access',
'access arguments' => array(
'view',
1,
3,
),
'page callback' => 'user_relationships_page',
'page arguments' => array(
1,
3,
),
'file' => 'user_relationships_ui.pages.inc',
);
}
$items["user/%user/relationships/requested/%user_relationships/%"] = array(
'title' => 'Approve Relationship',
'type' => MENU_CALLBACK,
'access callback' => 'user_relationships_ui_check_access',
'access arguments' => array(
'request',
1,
),
'page callback' => 'user_relationships_ui_pending_requested_ajax',
'page arguments' => array(
5,
1,
4,
),
'file' => 'user_relationships_ui.forms.inc',
);
$items['user/%user/relationships/%user_relationships/remove'] = array(
'title' => 'Remove relationship',
'type' => MENU_CALLBACK,
'access callback' => 'user_relationships_ui_check_access',
'access arguments' => array(
'delete',
1,
),
'page callback' => 'user_relationships_ui_remove_ajax',
'page arguments' => array(
1,
3,
),
'file' => 'user_relationships_ui.forms.inc',
);
return $items;
}
function user_relationships_ui_title_callback($rtid) {
return user_relationships_type_get_name(user_relationships_type_load($rtid), TRUE, FALSE, TRUE);
}
/**
* Title callback to display the amount of pending requests.
* @param $column
* Which column that should be checked: requester_id (sent) or requestee_id
* (received).
* @param $account
* For which account shall the title be displayed. Defaults to the current
* user.
* @return
* Title string for either the Sent or Received requests local tasks.
*/
function user_relationships_ui_title_callback_pending($column, $account = NULL) {
if (!$account || !is_object($account)) {
global $user;
$account = $user;
}
$count = user_relationships_load(array(
$column => $account->uid,
'approved' => FALSE,
), array(
'count' => TRUE,
));
if ($column == 'requester_id') {
if ($count > 0) {
return format_plural($count, 'Sent requests (1)', 'Sent requests (@count)');
}
return t('Sent requests');
}
else {
if ($count > 0) {
return format_plural($count, 'Received requests (1)', 'Received requests (@count)');
}
return t('Received requests');
}
}
/**
* Implements hook_user_login().
*/
function user_relationships_ui_user_login(&$edit, $account) {
if (user_relationships_ui_check_access('approve', NULL)) {
_user_relationships_ui_set_notifications($account);
}
}
function user_relationships_ui_user_view($account, $view_mode) {
global $user;
if ($account->uid == $user->uid && user_relationships_user_access('maintain @relationship relationships')) {
_user_relationships_ui_set_notifications($account);
return;
}
$output = array();
if ($list = user_relationships_ui_actions_between($user, $account, array(
'remove' => 1,
))) {
$output['relations'] = array(
'#title' => t('Your relationships to this user'),
'#type' => 'user_profile_item',
'#markup' => theme('item_list', array(
'items' => $list,
)),
'#attributes' => array(
'class' => array(
'user_relationships_ui',
),
),
);
}
if ($actions = user_relationships_ui_actions_between($user, $account, array(
'add' => 1,
'requested' => 1,
'received' => 1,
))) {
$output['actions'] = array(
'#title' => t('Relationship actions'),
'#type' => 'user_profile_item',
'#markup' => theme('item_list', array(
'items' => $actions,
)),
'#attributes' => array(
'class' => array(
'user_relationships_ui_actions',
),
),
);
}
if (sizeof($output)) {
$account->content['user_relationships_ui'] = array(
'#type' => 'user_profile_category',
'#title' => t('Relationships'),
'#weight' => 10,
);
$account->content['user_relationships_ui'] = array_merge($account->content['user_relationships_ui'], $output);
}
}
/**
* Implements hook_form_alter().
*/
function user_relationships_ui_form_alter(&$form, &$form_state, $form_id) {
if (($form_id == 'user_register_form' || $form_id == 'user_profile_form') && $form['#user_category'] == 'account') {
// Create array to be able to merge in fieldset and avoid overwriting
// already added options.
if (!isset($form['user_relationships_ui_settings'])) {
$form['user_relationships_ui_settings'] = array();
}
// Always create the fieldset in case other modules want to add
// related settings through hook_form_alter(). If it's still empty after the
// build process, the after build function will remove it.
$form['user_relationships_ui_settings'] += array(
'#type' => 'fieldset',
'#title' => t('Relationships'),
'#weight' => 5,
'#collapsible' => TRUE,
'#after_build' => array(
'user_relationships_ui_account_fieldset_remove_if_empty',
),
);
if (variable_get('user_relationships_ui_require_approval', TRUE)) {
if (variable_get('user_relationships_allow_auto_approve', FALSE) && ($relationships = user_relationships_types_load())) {
if (!isset($form['#user']->data['user_relationships_ui_auto_approve']) || !is_array($form['#user']->data['user_relationships_ui_auto_approve'])) {
$form['#user']->data['user_relationships_ui_auto_approve'] = array();
}
$options = array();
foreach ($relationships as $relationship) {
if ($relationship->requires_approval && user_relationships_ui_check_access('approve', NULL, $relationship)) {
$options[$relationship->rtid] = user_relationships_type_get_name($relationship);
}
}
//#453090 Do nothing if there are no options.
if (count($options)) {
$form['user_relationships_ui_settings']['user_relationships_ui_auto_approve'] = array(
'#type' => 'checkboxes',
'#title' => t('Automatically approve relationship requests from other users'),
'#options' => $options,
'#default_value' => $form['#user']->data['user_relationships_ui_auto_approve'],
'#description' => t("When another user requests a relationship with you, we usually require your approval. If you'd like certain relationship types to be approved automatically, check the box next to that type."),
);
}
}
}
}
}
/**
* Hides the settings fieldset if there are no options to be displayed.
*/
function user_relationships_ui_account_fieldset_remove_if_empty($element) {
// Go through all child elements, if any of them is visible, do not hide.
// If no elements exist or none are accessible, hide this element.
foreach (element_children($element) as $key) {
if (!isset($element[$key]['#access']) || $element[$key]['#access']) {
return $element;
}
}
$element['#access'] = FALSE;
return $element;
}
/**
* Implements hook_user_presave().
*/
function user_relationships_ui_user_presave(&$edit, $account, $category) {
$edit['data']['user_relationships_ui_auto_approve'] = isset($edit['user_relationships_ui_auto_approve']) ? $edit['user_relationships_ui_auto_approve'] : array();
}
/**
* Implements hook_theme().
*/
function user_relationships_ui_theme() {
$theme_funcs = array(
'user_relationships_request_relationship_link' => array(
'variables' => array(
'relate_to' => NULL,
),
),
'user_relationships_request_relationship_direct_link' => array(
'variables' => array(
'relate_to' => NULL,
'relationship_type' => NULL,
),
),
'user_relationships_remove_link' => array(
'variables' => array(
'uid' => NULL,
'rid' => NULL,
),
),
'user_relationships_pending_request_approve_link' => array(
'variables' => array(
'uid' => NULL,
'rid' => NULL,
),
),
'user_relationships_pending_request_disapprove_link' => array(
'variables' => array(
'uid' => NULL,
'rid' => NULL,
),
),
'user_relationships_pending_request_cancel_link' => array(
'variables' => array(
'uid' => NULL,
'rid' => NULL,
),
),
'user_relationships_approval_status' => array(
'variables' => array(
'approved' => NULL,
),
),
'user_relationships_user_link' => array(
'variables' => array(
'uid' => NULL,
),
),
);
foreach ($theme_funcs as $key => $val) {
$theme_funcs[$key]['file'] = 'user_relationships_ui.theme.inc';
}
$theme_templates = array(
'user_relationships' => array(
'variables' => array(
'account' => NULL,
'rtid' => NULL,
),
'path' => drupal_get_path('module', 'user_relationships_ui') . '/templates',
'template' => 'user_relationships',
),
'user_relationships_pending_requests' => array(
'variables' => array(
'account' => NULL,
),
'path' => drupal_get_path('module', 'user_relationships_ui') . '/templates',
'template' => 'user_relationships_pending_requests',
),
);
return array_merge($theme_funcs, $theme_templates);
}
/**
* Implements hook_field_extra_fields().
*/
function user_relationships_ui_field_extra_fields() {
$extra['user']['user'] = array(
'form' => array(
'user_relationships_ui_settings' => array(
'label' => t('Relationships'),
'description' => t('User Relationships settings form.'),
'weight' => 5,
),
),
'display' => array(
'user_relationships_ui' => array(
'label' => t('Relationships'),
'description' => t('User Relationships relations and actions.'),
'weight' => 10,
),
),
);
return $extra;
}
/**
* Implements hook_form_FORM_ID_alter().
*/
function user_relationships_ui_form_user_relationships_admin_type_edit_alter(&$form, &$form_state) {
$form['listings'] = array(
'#type' => 'fieldset',
'#title' => t('Listings'),
'#group' => 'tabs',
);
// Load settings.
$settings = db_query('SELECT * FROM {user_relationships_ui_settings} WHERE rtid = :rtid', array(
':rtid' => (int) $form['rtid']['#value'],
))
->fetchObject();
$form['listings']['ui_settings_hide'] = array(
'#type' => 'checkbox',
'#title' => t('Hide this relationship type from the relationships list'),
'#default_value' => $settings ? $settings->hide : FALSE,
);
$form['listings']['ui_settings_show_tab'] = array(
'#type' => 'checkbox',
'#title' => t('Create a separate tab (and path) for this relationship type'),
'#default_value' => $settings ? $settings->show_tab : FALSE,
);
}
/**
* Implements hook_user_relationships_type_insert().
*/
function user_relationships_ui_user_relationships_type_insert($relationship_type) {
db_merge('user_relationships_ui_settings')
->key(array(
'rtid' => $relationship_type->rtid,
))
->fields(array(
'hide' => isset($relationship_type->ui_settings_hide) ? (int) $relationship_type->ui_settings_hide : 0,
'show_tab' => isset($relationship_type->ui_settings_show_tab) ? (int) $relationship_type->ui_settings_show_tab : 0,
))
->execute();
}
/**
* Implements hook_user_relationships_type_update().
*/
function user_relationships_ui_user_relationships_type_update($relationship_type) {
db_merge('user_relationships_ui_settings')
->key(array(
'rtid' => $relationship_type->rtid,
))
->fields(array(
'hide' => isset($relationship_type->ui_settings_hide) ? (int) $relationship_type->ui_settings_hide : 0,
'show_tab' => isset($relationship_type->ui_settings_show_tab) ? (int) $relationship_type->ui_settings_show_tab : 0,
))
->execute();
}
/**
* Implements hook_user_relationships_type_delete().
*/
function user_relationships_ui_user_relationships_type_delete($rtype) {
db_delete('user_relationships_ui_settings')
->condition('rtid', $rtype->rtid)
->execute();
}
Functions
Constants
Name | Description |
---|---|
USER_RELATIONSHIPS_UI_PATH | @file UI components of user_relationships @author Jeff Smick (creator) @author Alex Karshakevich (maintainer) http://drupal.org/user/183217 @author Darren Ferguson (contributor) http://drupal.org/user/70179 |