* @file * Allows admins to create implied relationships (eg: Manager implies Coworker) */ /** * Public API to load an implied relationship * * @param $riid * integer of the implied relationship ID * * @return * object with the relationship_type object and implied relationship_type object */ function user_relationship_implications_implied_load($riid) { static $implied_relationships = array(); $implications = array(); if (!isset($implied_relationships[$riid])) { $results = db_query("SELECT * FROM {user_relationship_implications} WHERE riid = %d", $riid); $implications = _user_relationship_implications_load_data($results); $implied_relationships[$riid] = $implications[0]; } return $implied_relationships[$riid]; } /** * Public API to load all implied relationships * * @return * array of relationship implications */ function user_relationship_implications_load() { static $implications = array(); if (!sizeof($implications)) { $results = db_query("SELECT * FROM {user_relationship_implications}"); $implications = _user_relationship_implications_load_data($results); } return $implications; } /** * hook_form_alter() */ function user_relationship_implications_form_alter($form_id, &$form) { switch ($form_id) { case 'user_relationships_type_edit': $relationship_type = $form['relationship_type']['#value']; $relationship_types = user_relationships_relationship_types_load(); $implied_by = array(); if ($relationship_type) { foreach ($relationship_type->implies as $implies) { $values[$implies->implies_rtid] = $implies->implies_rtid; } foreach ($relationship_type->implied_by as $implied) { $implied_by[] = $implied->rtid; } } foreach ($relationship_types as $type) { if ($type->rtid != $relationship_type->rtid && !in_array($type->rtid, $implied_by)) { $options[$type->rtid] = $type->name; } } if (sizeof($options)) { $form['implications'] = array( '#title' => t('This relationship implies'), '#type' => 'checkboxes', '#options' => $options, '#value' => $values, '#description' => t('Users will automatically have these relationships created between them also. (ex: Manager implies Coworker)'), '#weight' => 0, ); $form['#submit'] += array('user_relationship_implications_edit_submit' => array()); } break; } } /** * Edit relationship type submission processor */ function user_relationship_implications_edit_submit($form_id, &$form_values) { // the rtid is in a different place when adding a new type vs. editing an existing type if (isset($form_values['relationship_type']) && !is_null($form_values['relationship_type'])) { // editing an existing relationship type $rtid = $form_values['relationship_type']->rtid; } else { // adding a new relationship type - go figure $rtid = $form_values['rtid']; } db_query("DELETE FROM {user_relationship_implications} WHERE rtid = %d", $rtid); foreach ($form_values['implications'] as $implied_rtid) { if ($implied_rtid) { db_query( "INSERT INTO {user_relationship_implications} (riid, rtid, implies_rtid) VALUES (%d, %d, %d)", db_next_id('{user_relationship_implications}_id'), $rtid, $implied_rtid ); } } } /** * hook_user_relationships() */ function user_relationship_implications_user_relationships($type, &$relationship, $category = NULL) { switch ($type) { case 'load type': if ($relationship->rtid) { static $loaded_relationship_implications = array(); if (!is_array($loaded_relationship_implications[$relationship->rtid])) { $loaded_relationship_implications[$relationship->rtid] = array(); $results = db_query( "SELECT * FROM {user_relationship_implications} WHERE rtid = %d OR implies_rtid = %d", $relationship->rtid, $relationship->rtid ); while ($implication = db_fetch_object($results)) { $loaded_relationship_implications[$relationship->rtid][] = $implication; } } $relationship->implies = array(); $relationship->implied_by = array(); foreach ($loaded_relationship_implications[$relationship->rtid] as $implication) { if ($implication->rtid == $relationship->rtid) { $relationship->implies[] = $implication; } else { $relationship->implied_by[] = $implication; } } } break; case 'delete type': if ($relationship->rtid) { $results = db_query( "DELETE FROM {user_relationship_implications} WHERE rtid = %d OR implies_rtid = %d", $relationship->rtid, $relationship->rtid ); // clean out the implications cache static $loaded_relationship_implications; unset($loaded_relationship_implications); } break; case 'insert': case 'update': if ($relationship->type->implies) { // if the type of the relationship we're inserting or updating implies other relationship type(s), // loop through the implied relationship types and do the right thing foreach ($relationship->type->implies as $implied) { // load all the pre-existing relationships between these two users of the implied relationship type $relationships = user_relationships_load_relationships(array( 'uid1' => $relationship->requester_id, 'uid2' => $relationship->requestee_id, 'rtid' => $implied->implies_rtid, ) ); // if there aren't any, create one with the same approved status as the relationship we're inserting/updateing if (sizeof($relationships) == 0) { $implied = user_relationships_relationship_type_load(array('rtid' => $implied->implies_rtid)); user_relationships_request_relationship($relationship->requester, $relationship->requestee, $implied, $relationship->approved); } // if there are some, then if we're approving this relationship, approve the pre-existing one(s) too else { foreach ($relationships as $existing) { if ($relationship->approved && !$existing->approved) { // approve the relationship $approved = user_relationships_relationship_load($existing->rid); $approved->approved = TRUE; user_relationships_update_relationship($existing, $approved); // set the message informing the user (use requester and requestee from original relationship) $requester = user_load(array('uid' => $relationship->requester_id)); $requestee = user_load(array('uid' => $relationship->requestee_id)); drupal_set_message(user_relationships_get_message('accepted', array( '!requester' => theme('username', $requester), '!requestee' => theme('username', $requestee), '%relationship_name' => $approved->name, '%relationship_plural_name' => $approved->plural_name, ))); } } } } } break; case 'delete': global $user; if ($relationship->type->implied_by) { // if the type of the relationship we're deleting is implied by other relationship type(s), // loop through the implying relationship types and do the right thing foreach ($relationship->type->implied_by as $implied_by) { // load all the pre-existing relationships between these two users of the implying relationship type $relationships = user_relationships_load_relationships(array( 'uid1' => $relationship->requester_id, 'uid2' => $relationship->requestee_id, 'rtid' => $implied_by->rtid, ) ); // if they're not oneway relationships, or if they are and the requester is the one doing the deleting, // then delete the implying relationships foreach ($relationships as $existing) { $rtype = user_relationships_relationship_type_load(array('rtid' => $existing->rtid)); if (!$rtype->is_oneway || $relationship->requester_id == $user->uid) { // delete the relationship $relationship_to_delete = user_relationships_relationship_load($existing->rid); user_relationships_delete_relationship($relationship_to_delete, $relationship->deleted_by, $category); // set the message informing the user (use requester and requestee from original relationship) $requester = user_load(array('uid' => $relationship->requester_id)); $requestee = user_load(array('uid' => $relationship->requestee_id)); drupal_set_message(user_relationships_get_message('removed', array( '!requester' => theme('username', $requester), '!requestee' => theme('username', $requestee), '%relationship_name' => $relationship_to_delete->name, '%relationship_plural_name' => $relationship_to_delete->plural_name, ))); } } } } break; } } /** * hook_user_relationships_page_alter() */ function user_relationship_implications_user_relationships_page_alter($page_id, &$page, &$table) { switch ($page_id) { case 'types list': array_splice($table['headers'], 2, 0, t('Implies')); foreach ($table['data'] as $key => $relationship) { $relationship = user_relationships_relationship_type_load(array('rtid' => $relationship->rtid)); array_splice($table['rows'][$key], 2, 0, ' '); $names = array(); foreach ($relationship->implies as $implied) { $implied = user_relationship_implications_implied_load($implied->riid); $names[] = $implied->implies_relationship_type->name; } $table['rows'][$key][2] = implode(', ', $names); } break; } } /** * Categorized list of relationships for a given user */ function theme_user_relationship_implications_page($uid = NULL, $relationship = NULL) { global $user; if (empty($uid)) { $viewed_user =& $user; } else { $viewed_user = user_load(array('uid' => $uid)); } // Check that the uid is valid, not the anonymous user, and the user exists if ($viewed_user->uid == 0) { drupal_not_found(); exit(); } $query = "SELECT r.*, rt.name, rt.is_oneway FROM {user_relationships} r, {user_relationship_types} rt WHERE (requester_id = %d OR requestee_id = %d) AND r.approved = 1 AND r.rtid = rt.rtid"; $args = array($viewed_user->uid, $viewed_user->uid); if (isset($relationship->rtid)) { $query .= " AND r.rtid = %d"; $args[] = $relationship->rtid; } $relationships_per_page = variable_get('user_relationships_relationships_per_page', 16); $result = $relationships_per_page ? pager_query($query, $relationships_per_page, 0, NULL, $args) : db_query($query, $args); if (db_num_rows($result)) { $edit_access = ($user->uid == $uid && user_access('maintain relationships')) || user_access('administer users'); $online_interval = time() - variable_get('user_block_seconds_online', 180); while ($relation = db_fetch_object($result)) { $this_user = $viewed_user->uid == $relation->requestee_id ? 'requester_id' : 'requestee_id'; $this_user = user_load(array('uid' => $relation->$this_user)); $relations = array(); $this_users_relationships = user_relationships_load_all_for_user($this_user->uid); $rows[] = array( theme('username', $this_user), theme('item_list', _user_relationship_implications_load_relationship_names($this_users_relationships, $viewed_user->uid)), $this_user->access > $online_interval ? t('online') : t('not online'), $edit_access ? theme('user_relationships_remove_link', $viewed_user->uid, $relation) : ' ', ); } $output .= theme('table', array(), $rows); } else { $output .= t('No relationships found'); } $output .= theme('pager', NULL, $relationships_per_page); drupal_set_title(t("%username's %relationships", array( '%username' => $viewed_user->name, '%relationships' => $relationship->plural_name ? $relationship->plural_name : t('relationships') ))); return $output; } /** * Helper functions (not for general use!!) */ function _user_relationship_implications_load_data(&$results) { $implications = array(); while ($implication = db_fetch_object($results)) { $implication->relationship_type = user_relationships_relationship_type_load(array('rtid' => $implication->rtid)); $implication->implies_relationship_type = user_relationships_relationship_type_load(array('rtid' => $implication->implies_rtid)); $implications[] = $implication; } return $implications; } function _user_relationship_implications_load_relationship_names($relationships, $uid) { $output = array(); foreach ($relationships as $relationship) { if ($relationship->requester_id == $uid || $relationship->requestee_id == $uid) { $output[] = $relationship->name; } } return $output; }