You are here

user_relationship_implications.module in User Relationships 5

Drupal Module: User Relationship Implications

@author: Jeff Smick <sprsquish [at] gmail [dot] com>

Allows admins to create implied relationships (eg: Manager implies Coworker)

File

plugins/user_relationship_implications/user_relationship_implications.module
View source
<?php

/**
 * Drupal Module: User Relationship Implications
 *
 * @author: Jeff Smick <sprsquish [at] gmail [dot] com>
 * @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);
          }
          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, '&nbsp;');
        $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 \n      FROM {user_relationships} r, {user_relationship_types} rt\n      WHERE (requester_id = %d OR requestee_id = %d)\n        AND r.approved = 1\n        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) : '&nbsp;',
      );
    }
    $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;
}

Functions

Namesort descending Description
theme_user_relationship_implications_page Categorized list of relationships for a given user
user_relationship_implications_edit_submit Edit relationship type submission processor
user_relationship_implications_form_alter hook_form_alter()
user_relationship_implications_implied_load Public API to load an implied relationship
user_relationship_implications_load Public API to load all implied relationships
user_relationship_implications_user_relationships hook_user_relationships()
user_relationship_implications_user_relationships_page_alter hook_user_relationships_page_alter()
_user_relationship_implications_load_data Helper functions (not for general use!!)
_user_relationship_implications_load_relationship_names