$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 '. "(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})"; $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('DISTINCT ur.rid', 'ur.*', 'urt.*'); $joins = array('INNER 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( '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} GROUP BY rid {$extra}", 'count' => "SELECT COUNT(DISTINCT 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 { $type = is_numeric(current($value)) ? 'int' : 'varchar'; return 'IN ('.db_placeholders($value, $type).')'; } } 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'"; } } /********************* * HOOKS *********************/ /** * Implementation of hook_perm(). */ function user_relationships_api_perm() { return array( 'can have relationship', ); } /** * Implementation of hook_user(). */ 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); } } /** * Implementation of hook_cron(). */ function user_relationships_api_cron() { $now = time(); // only expire relationships once a day $last_cron = variable_get('user_relationships_last_expire', 0); if ($now > $last_cron + (24 * 60 * 60)) { return FALSE; } switch ($GLOBALS['db_type']) { case 'mysql': case 'mysqli': db_query( " DELETE ur FROM user_relationships ur INNER JOIN user_relationship_types urt USING ( rtid ) WHERE ur.approved = 0 AND urt.expires_val > 0 AND %d > (ur.updated_at + (urt.expires_val * 24 * 60 *60))", $now ); break; } // remember when we last expired relationships variable_set('user_relationships_last_expire', $now); return TRUE; }