array( 'submitted' => 'Your request to be a %relationship_name of !requestee has been submitted.', 'accepted' => 'You are now a %relationship_name of !requester.', 'disapproved' => "!requester's request to be a %relationship_name of !requestee has been removed.", 'cancel' => 'Your request to be a %relationship_name of !requestee has been canceled.', 'default' => 'No action has been taken.', 'removed' => '!requester is no longer a %relationship_name of !requestee.', 'pending' => '!requester believes they are a %relationship_name of yours. Please view your !pending_relationship_requests to approve them.', 'pre_approved' => "You're request to be %relationship_name of !requestee has been automatically approved. You are now a %relationship_name of !requestee." ), 'error' => array( 'too_many_relationships' => 'You already relate to this user in every possible way.', 'existing_request' => 'You have already requested to be a %relationship_name of !requestee', 'existing_relationship' => 'You are already a %relationship_name of !requestee', 'not_accepting_requests' => 'This user is not accepting relationship requests.', 'self_request' => 'You are not allowed to create a relationship to yourself.', 'non_existant_user' => 'This user does not exist.', 'non_existant_type' => 'That relationship type does not exist', 'unknown_error' => 'An unknown error occurred. Please contact the site administrator', ), ); } /** * Recursively search an array for a key and return the value attached to it */ function _user_relationships_get_from_array($needle, &$haystack) { foreach ($haystack as $key => $value) { if ($key == $needle) { return $value; } else if (is_array($value)) { if ($msg = _user_relationships_get_from_array($needle, $value)) { return $msg; } } } } /** * Invoke hook_user_relationships() */ function _user_relationships_invoke($type, &$relationship, $category = NULL) { foreach (module_list() as $module) { $function = $module .'_user_relationships'; if (function_exists($function)) { $function($type, $relationship, $category); } } } /** * Adds autocompletion capability */ function _user_relationships_autocomplete_types($string = '') { $matches = array(); if ($string) { $result = db_query_range("SELECT name FROM {user_relationship_types} WHERE LOWER(name) LIKE LOWER('%%%s%%')", strtolower($string), 0, 10); while ($relationship = db_fetch_object($result)) { $matches[$relationship->name] = check_plain($relationship->name); } } print drupal_to_js($matches); exit(); } /* * Notify the user of pending relationship requests */ function _user_relationships_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 = $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'), "relationships/requests") )); if (!in_array($msg, $notifications)) { drupal_set_message($msg); } } } /** * List of relationships between two users */ function _user_relationships_between(&$viewer, &$viewed) { $list = array(); $relationships = user_relationships_load(array('requester_id' => $viewer->uid, 'requestee_id' => $viewed->uid)); foreach ($relationships as $relationship) { if ($relationship->approved && !$list[$relationship->rid]) { $list[$relationship->rid] = t('%relationship_name (!remove_link)', array( '%relationship_name' => $relationship->name, '!remove_link' => theme('user_relationships_remove_link', $viewer->uid, $relationship->rid) )); } } return $list; } /** * List of pending relationships with between two users */ function _user_relationships_actions_between(&$viewer, &$viewed) { if ($viewer->uid == $viewed->uid) { return; } $list = array(); $relationships = user_relationships_load(array('requester_id' => $viewer->uid, 'requestee_id' => $viewed->uid, 'approved' => FALSE)); foreach ($relationships as $relationship) { $list[] = t('You have requested to be a %relationship_name of this user. (!pending_requests)', array( '%relationship_name' => $relationship->name, '!pending_requests' => l(t('pending requests'), "relationships/requests"), )); } $relationships = user_relationships_load(array('requester_id' => $viewed->uid, 'requestee_id' => $viewer->uid, 'approved' => FALSE)); foreach ($relationships as $relationship) { $list[] = t('This user believes that they are a %relationship_name of yours. (!pending_requests)', array( '%relationship_name' => $relationship->name, '!pending_requests' => l(t('pending requests'), "user/{$viewer->uid}/relationships/requests"), )); } $types_count = (int)db_result(db_query("SELECT COUNT(*) FROM {user_relationship_types}")); if ( variable_get('user_relationships_allow_multiple', TRUE) && (user_relationships_load(array('between' => array($viewer->uid, $viewed->uid)), TRUE) < $types_count) ) { $list[] = theme('user_relationships_request_relationship_link', $viewed); } return $list; } /** * Helper function to build the settings form for the notification messages */ function _user_relationships_message_settings_form(&$form, $defaults = array()) { foreach ($defaults as $key => $value) { if (is_array($value)) { $form[$key] = array( '#type' => 'fieldset', '#title' => ucfirst(str_replace('_',' ',$key)), '#collapsible' => TRUE, '#collapsed' => TRUE ); _user_relationships_message_settings_form($form[$key], $value); } else { $form["user_relationships_msg_{$key}"] = array( '#type' => 'textfield', '#title' => ucfirst(str_replace('_',' ',$key)), '#default_value' => variable_get("user_relationships_msg_{$key}", $value) ); } } } /** * Create the new relationship */ function _user_relationships_save_relationship(&$relationship, $op = 'create') { if (!isset($relationship->flags)) { $relationship->flags = UR_OK; } _user_relationships_invoke('pre-save', $relationship, $op); if (!$relationship->created_at) { $relationship->created_at = time(); } if ($relationship->rid) { db_query("DELETE FROM {user_relationships} WHERE rid = %d", $relationship->rid); } else { $relationship->rid = db_result(db_query("SELECT MAX(rid) FROM {user_relationships}")) + 1; } $relationship->updated_at = time(); if (!drupal_write_record('user_relationships', $relationship)) { return FALSE; } $relationship_type = user_relationships_type_load($relationship->rtid); if ($relationship->approved && !$relationship_type->is_oneway) { // PHP 4 doens't have the "clone" keyword $relationship_copy = version_compare(phpversion(), '5', '>=') ? clone $relationship : $relationship; $relationship_copy->requester_id = $relationship->requestee_id; $relationship_copy->requestee_id = $relationship->requester_id; drupal_write_record('user_relationships', $relationship_copy); } _user_relationships_invoke('post-save', $relationship, $op); return $relationship; } /** * Helper function to generate queries from a list of parameters */ function _user_relationships_generate_query($param = array(), $order = NULL, $limit = NULL, $include_user_info = FALSE) { // Turn the conditions into a query. foreach ($param as $key => $value) { if (!isset($value)) { continue; } $operator = _user_relationship_process_query_argument($key, $value); switch ($key) { case 'between': $cond[] = "((ur.requester_id {$operator[0]} AND ur.requestee_id {$operator[1]})". ' OR '. "((urt.is_oneway = 1 OR ur.approved = 0) AND ur.requestee_id {$operator[0]} AND ur.requester_id {$operator[1]}))"; $arguments[] = $value[0]; $arguments[] = $value[1]; $arguments[] = $value[0]; $arguments[] = $value[1]; break; case 'user': $cond[] = "(ur.requester_id {$operator} OR (ur.requestee_id {$operator} AND urt.is_oneway = 1))"; $arguments[] = $value; $arguments[] = $value; break; default: $types_cols = array('name','plural_name','is_oneway','requires_approval','expires_val'); $cond[] = "%s.%s {$operator}"; $arguments[] = !in_array($key, $types_cols) ? 'ur' : 'urt'; $arguments[] = $key; $arguments[] = $value; } } $selects = array('ur.rid', 'ur.*', 'urt.*'); $joins = array('LEFT JOIN {user_relationship_types} urt USING(rtid)'); // We wont need anything after this point for the count SQL $count_joins = implode(' ', $joins); if ($include_user_info) { $selects = array_merge($selects, array( 'requesters.name AS requester_name', 'requestees.name AS requestee_name', 'requesters.mail AS requester_mail', 'requestees.mail AS requestee_mail', 'requesters.data AS requester_data', 'requestees.data AS requestee_data', 'requesters.picture AS requester_picture', 'requestees.picture AS requestee_picture', )); $joins = array_merge($joins, array( 'LEFT JOIN {users} requesters ON ur.requester_id = requesters.uid', 'LEFT JOIN {users} requestees ON ur.requestee_id = requestees.uid' )); } $selects = implode(',', $selects); $joins = implode(' ', $joins); $cond = $cond ? 'WHERE '.implode(' AND ', $cond) : ''; $extra = array(); if (!empty($order)) { $extra[] = "ORDER BY {$order}"; } if (!empty($limit)) { $extra[] = "LIMIT {$limit}"; } $extra = implode(' ', $extra); return array( 'query' => "SELECT {$selects} FROM {user_relationships} ur {$joins} {$cond} {$extra}", 'count' => "SELECT COUNT(rid) AS count FROM {user_relationships} ur {$count_joins} {$cond}", 'arguments' => $arguments, ); } /** * Helper function to process the various argument types allowed */ function _user_relationship_process_query_argument($key, &$value) { if ($key == 'between') { return array( _user_relationship_process_query_argument(NULL, $value[0]), _user_relationship_process_query_argument(NULL, $value[1]), ); } if (is_array($value)) { if (count($value) == 1) { $value = array_shift($value); return _user_relationship_process_query_argument($key, $value); } else { $value = implode(',', $value); return 'IN (%s)'; } } else if (is_numeric($value) || is_bool($value)) { $value = (int)$value; return '= %d'; } else if (preg_match('/([<>=]{1,2})\s*(.+)/', $value, $matches)){ $marker = "'%s'"; $value = $matches[3]; if (is_numeric($value)) { $marker = '%d'; $value = (int)$value; } return "{$matches[1]} {$marker}"; } else { return "= '%s'"; } } /** * Check access callback */ function user_relationships_check_access($types, $account = NULL) { global $user; if (user_access('administer users')) { return TRUE; } $access = FALSE; if (!is_array($types)) { $types = array($types); } foreach ($types as $type) { switch ($type) { case 'view': $access = ($access || user_access('maintain relationships') | user_access('view user relationships')); case 'edit': $access = ($access || user_access('maintain relationships') & user_access('can have relationship')); case 'user': $access = ($access || ($account->uid == $user->uid)); } } return $access; } /** * Menu Argument; %relationship_type */ function relationship_type_load($rtid) { if (is_numeric($rtid)) { return user_relationships_type_load($rtid); } return FALSE; } /** * Menu Argument; %relationship */ function relationship_load($rid) { if (is_numeric($rid)) { return user_relationships_load($rid); } return FALSE; }