You are here

user_relationships.module in User Relationships 5.2

Same filename and directory in other branches
  1. 5 user_relationships.module
  2. 7 user_relationships.module

File

user_relationships.module
View source
<?php

/**
 *
 * This file contains utility functions for the User Relationships module
 * Please consult either the other files for public functions
 *
 */
define('UR_OK', 0x0);
define('UR_BANNED', 0x1);

// Load all needed files
foreach (array(
  'api',
  'theme',
  'hooks',
  'pages',
  'forms',
  'actions',
) as $file_to_include) {
  $modulepath = drupal_get_path('module', 'user_relationships');
  include_once "{$modulepath}/user_relationships_{$file_to_include}.inc";
}

/**
 * Returns a nested array of default messages
 */
function user_relationships_default_messages() {
  return array(
    'informational' => 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 pre-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.',
      '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'), "user/{$account->uid}/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),
      ));
    }
  }
  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'), "user/{$viewer->uid}/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"),
    ));
  }
  $rel_count = user_relationships_load(array(
    'requester_id' => $viewer->uid,
    'requestee_id' => $viewed->uid,
  ), TRUE);
  if ($rel_count < 1 || variable_get('user_relationships_allow_multiple', TRUE) && $rel_count < (int) db_result(db_query("SELECT COUNT(*) FROM {user_relationship_types}"))) {
    $list = array_merge($list, _user_relationships_get_create_relationship_links($viewed));
  }
  return $list;
}

/**
 * Render links to create relationship(s) with a user.
 *
 * @param $viewed user account to create links to.
 * @return array of one or more links to create relationships with the user
 */
function _user_relationships_get_create_relationship_links($viewed) {

  //this is a kludge to allow drawing links to each relationship when using user_relationships_direct.module
  if (module_exists('user_relationship_direct')) {
    return user_relationships_direct_create_relationship_links($viewed);
  }
  else {
    return array(
      theme('user_relationships_request_relationship_link', $viewed),
    );
  }
}

/**
 * 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) {

    // Delete the original request
    db_query('DELETE FROM {user_relationships} WHERE rid = %d', $relationship->rid);

    // Delete possible requests coming the other direction
    $relationship_type = user_relationships_type_load($relationship->rtid);
    if (!$relationship_type->is_oneway) {
      db_query('DELETE FROM {user_relationships} WHERE rtid = %d AND requester_id = %d AND requestee_id = %d', $relationship->rtid, $relationship->requestee_id, $relationship->requester_id);
    }
  }
  else {
    $relationship->rid = db_next_id('{user_relationships}_id');
  }
  $queries = array();
  $relationship_type = user_relationships_type_load($relationship->rtid);
  $query = 'INSERT INTO {user_relationships} (rid, requester_id, requestee_id, rtid, approved, created_at, updated_at, flags) VALUES';
  $insertions = '(%d, %d, %d, %d, %d, %d, %d, %d)';
  $arguments = array(
    $relationship->rid,
    $relationship->requester_id,
    $relationship->requestee_id,
    $relationship->rtid,
    $relationship->approved,
    $relationship->created_at,
    time(),
    $relationship->flags,
  );
  $queries[] = array(
    "{$query} {$insertions}",
    $arguments,
  );
  if ($relationship->approved && !$relationship_type->is_oneway) {
    $requester = $arguments[1];
    $arguments[1] = $arguments[2];
    $arguments[2] = $requester;
    $queries[] = array(
      "{$query} {$insertions}",
      $arguments,
    );
  }
  foreach ($queries as $query) {
    if (db_query($query[0], $query[1]) === FALSE) {

      // If this ever happens we have major problems
      return FALSE;
    }
  }
  _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 ((urt.is_oneway = 1 OR ur.approved = 0) AND ur.requestee_id {$operator}))";
        $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'";
      }
    }
  }
}

Functions

Namesort descending Description
user_relationships_default_messages Returns a nested array of default messages
_user_relationships_actions_between List of pending relationships with between two users
_user_relationships_autocomplete_types Adds autocompletion capability
_user_relationships_between List of relationships between two users
_user_relationships_generate_query Helper function to generate queries from a list of parameters
_user_relationships_get_create_relationship_links Render links to create relationship(s) with a user.
_user_relationships_get_from_array Recursively search an array for a key and return the value attached to it
_user_relationships_invoke Invoke hook_user_relationships()
_user_relationships_message_settings_form Helper function to build the settings form for the notification messages
_user_relationships_save_relationship Create the new relationship
_user_relationships_set_notifications
_user_relationship_process_query_argument Helper function to process the various argument types allowed

Constants

Namesort descending Description
UR_BANNED
UR_OK This file contains utility functions for the User Relationships module Please consult either the other files for public functions