View source  
  <?php
define('UR_OK', 0x0);
define('UR_BANNED', 0x1);
foreach (array(
  'api',
  'actions',
  'socnet',
) as $file) {
  module_load_include("inc", "user_relationships_api", "user_relationships_api.{$file}");
}
if (module_exists('privatemsg')) {
  module_load_include('inc', 'user_relationships_api', 'user_relationships_api.privatemsg');
}
function _user_relationships_invoke($type, &$relationship, $is_type = FALSE) {
  $hook = 'user_relationships' . ($is_type ? '_type' : '');
  foreach (module_implements($hook) as $module) {
    $function = $module . '_' . $hook;
    $function($type, $relationship);
  }
}
function _user_relationships_generate_query($param = array(), $options = array()) {
  extract($options, EXTR_SKIP);
  
  $relationship_types = user_relationships_types_load();
  $oneway_relationship_type_ids = array();
  foreach ($relationship_types as $rt) {
    if ($rt->is_oneway) {
      $oneway_relationship_type_ids[] = $rt->rtid;
    }
  }
  $oneway_relationship_types_in = implode(",", $oneway_relationship_type_ids);
  $twoway_reverse_clause = FALSE;
  
  
  foreach ($param as $key => $value) {
    if (!isset($value)) {
      continue;
    }
    $operator = _user_relationship_process_query_argument($key, $value);
    switch ($key) {
      case 'between':
        $between_cond = "((ur.requester_id {$operator[0]} AND ur.requestee_id {$operator[1]}) OR (";
        
        if (!isset($include_twoway_reverse)) {
          if (!empty($oneway_relationship_types_in)) {
            $between_cond .= '(ur.approved <> 1 OR ur.rtid IN (' . $oneway_relationship_types_in . ')) AND ';
          }
          else {
            $between_cond .= '(ur.approved <> 1) AND ';
          }
          $twoway_reverse_clause = TRUE;
        }
        $between_cond .= "ur.requestee_id {$operator[0]} AND ur.requester_id {$operator[1]}))";
        $cond[] = $between_cond;
        $arguments[] = $value[0];
        $arguments[] = $value[1];
        $arguments[] = $value[0];
        $arguments[] = $value[1];
        break;
      case 'user':
        
        if (!isset($include_twoway_reverse)) {
          if (!empty($oneway_relationship_types_in)) {
            $cond[] = "(ur.requester_id {$operator} OR ((ur.approved <> 1 OR ur.rtid IN (" . $oneway_relationship_types_in . ")) AND ur.requestee_id {$operator}))";
          }
          else {
            $cond[] = "(ur.requester_id {$operator} OR (ur.approved <> 1 AND ur.requestee_id {$operator}))";
          }
          $twoway_reverse_clause = TRUE;
        }
        else {
          $cond[] = "(ur.requester_id {$operator} OR ur.requestee_id {$operator})";
        }
        $arguments[] = $value;
        $arguments[] = $value;
        break;
      case 'rid':
      case 'requester_id':
      case 'requestee_id':
        $twoway_reverse_clause = TRUE;
      
      default:
        $types_cols = array(
          'name',
          'plural_name',
          'is_oneway',
          'is_reciprocal',
          'requires_approval',
          'expires_val',
        );
        $cond[] = "%s.%s {$operator}";
        $arguments[] = !in_array($key, $types_cols) ? 'ur' : 'urt';
        $arguments[] = $key;
        
        if (!is_array($value)) {
          $arguments[] = $value;
        }
        else {
          $arguments = array_merge($arguments, $value);
        }
    }
  }
  
  if (!$twoway_reverse_clause && !isset($include_twoway_reverse)) {
    if (!empty($oneway_relationship_types_in)) {
      $cond[] = '(ur.rtid IN (' . $oneway_relationship_types_in . ') OR ur.approved <> 1 OR ur.requester_id < ur.requestee_id)';
    }
    else {
      $cond[] = '(ur.approved <> 1 OR ur.requester_id < ur.requestee_id)';
    }
    $twoway_reverse_clause = TRUE;
  }
  $selects = array(
    'DISTINCT ur.rid',
    'ur.*',
    'urt.*',
  );
  $joins = array(
    'INNER JOIN {user_relationship_types} urt ON ur.rtid = urt.rtid',
  );
  
  $count_joins = implode(' ', $joins);
  if (isset($include_user_info) && $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(
      'INNER JOIN {users} requesters ON ur.requester_id = requesters.uid',
      'INNER 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 = is_array($extra) ? implode(' ', $extra) : $extra;
  return array(
    
    'query' => "SELECT {$selects} FROM {user_relationships} ur {$joins} {$cond} {$extra}",
    'count' => "SELECT COUNT(DISTINCT rid) AS count FROM {user_relationships} ur {$count_joins} {$cond}",
    'arguments' => $arguments,
  );
}
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 {
      $type = is_numeric(current($value)) ? 'int' : 'varchar';
      return 'IN (' . db_placeholders($value, $type) . ')';
    }
  }
  elseif (is_numeric($value) || is_bool($value)) {
    $value = (int) $value;
    return '= %d';
  }
  elseif (is_float($value)) {
    return '= %f';
  }
  elseif (preg_match('/([<>=]{1,2})\\s*(.+)/', $value, $matches)) {
    $marker = "'%s'";
    $value = $matches[2];
    if (is_numeric($value)) {
      $marker = '%d';
      $value = (int) $value;
    }
    return "{$matches[1]} {$marker}";
  }
  else {
    return "= '%s'";
  }
}
function user_relationships_api_perm() {
  return array(
    'can have relationships',
  );
}
function user_relationships_api_cron() {
  $now = time();
  
  $last_cron = variable_get('user_relationships_last_expire', 0);
  if ($now < $last_cron + 86400) {
    return FALSE;
  }
  $result = db_query(" SELECT ur.rid\n      FROM {user_relationships} ur\n        INNER JOIN {user_relationship_types} urt ON ur.rtid = urt.rtid\n      WHERE ur.approved = 0\n        AND urt.expires_val > 0\n        AND ur.updated_at < (%d - (urt.expires_val * 86400))\n      GROUP BY ur.rid", $now);
  $expired_requests = array();
  while ($request = db_fetch_object($result)) {
    $expired_requests[] = $request->rid;
  }
  if (count($expired_requests)) {
    db_query('DELETE FROM {user_relationships} WHERE rid IN (' . db_placeholders($expired_requests) . ')', $expired_requests);
    
    _user_relationships_invoke('delete', $expired_requests);
  }
  
  variable_set('user_relationships_last_expire', $now);
  return TRUE;
}
function user_relationships_api_user($type, &$edit, &$account, $category = NULL) {
  if ($type == 'delete') {
    db_query("DELETE FROM {user_relationships} WHERE requester_id = %d OR requestee_id = %d", $account->uid, $account->uid);
  }
}
function ur_tt($name, $string, $langcode = NULL, $update = FALSE) {
  if (module_exists('i18nstrings')) {
    return tt($name, $string, $langcode, $update);
  }
  else {
    return $string;
  }
}
function user_relationships_api_user_relationships($op, &$relationship) {
  if ($op != 'approve' && $op != 'request') {
    return;
  }
  if (module_exists('trigger')) {
    $aids = _trigger_get_hook_aids('user_relationships_api', $op);
    $context = array(
      'hook' => 'user_relationships_api',
      'op' => $op,
      'requester' => $relationship->requester,
      'requestee' => $relationship->requestee,
      'relationship' => $relationship,
    );
    
    actions_do(array_keys($aids), $relationship, $context);
  }
}
function user_relationships_api_activity_info() {
  $info = new stdClass();
  $info->api = 2;
  $info->name = 'user_relationships_api';
  $info->object_type = 'user_relationships_api';
  $info->objects = array(
    'Requester' => 'requester',
    'Requestee' => 'requestee',
    'Relationship' => 'relationship',
  );
  $info->hooks = array(
    'user_relationships_api' => array(
      'approve',
      'request',
    ),
  );
  foreach (user_relationships_types_load() as $type_obj) {
    $info->realms["user_relationships_" . $type_obj->rtid] = $type_obj->plural_name;
  }
  return $info;
}
function user_relationships_api_token_list($type = 'all') {
  $tokens = array();
  if ($type == 'requester') {
    $tokens['user_relationships_api'] = array(
      'requester' => t('The user who issued the connection request.'),
    );
  }
  elseif ($type == 'relationship') {
    $tokens['user_relationships_api'] = array(
      'requestee' => t('The user who approved the connnection request.'),
      'relationship-name' => t('The relationship name (singular form)'),
    );
  }
  return $tokens;
}
function user_relationships_api_token_values($type, $data = NULL, $options = array()) {
  if ($type == 'requester') {
    $r = $data;
    $token_values = array(
      'requester' => theme('username', user_load(array(
        'uid' => $r->uid,
      ))),
    );
  }
  elseif ($type == 'requestee') {
    $r = $data;
    $token_values = array(
      'requestee' => theme('username', user_load(array(
        'uid' => $r->uid,
      ))),
    );
  }
  elseif ($type == 'relationship') {
    
    if (is_array($data)) {
      foreach ($data as $object) {
        if (is_object($object)) {
          $r = $object;
          break;
        }
      }
    }
    else {
      $r = $data;
    }
    $r_type = user_relationships_type_load((int) $r->rtid);
    $token_values = array(
      'requestee' => theme('username', user_load(array(
        'uid' => $r->requestee_id,
      ))),
      'requester' => theme('username', user_load(array(
        'uid' => $r->requester_id,
      ))),
      'relationship-name' => theme('placeholder', $r_type->name),
    );
  }
  return isset($token_values) ? $token_values : NULL;
}