okay, this is the trend du jour - linkedin has been doing it for a while, facebook just started doing it...basic idea:
User A has friends E, D, H
User B has friend C, F
User E has friends A, B, H, M
User A looks at his friends and sees B E and D, looks at User E and sees friends in common (H and B) but when viewing that same profile (or content created by any 'friend' he also sees a BLOCK that displays 2nd degree connections through "all user A friends" (E, D, H) as "people you might know" (in this case it would include B, M, C, F)
it's simply running all users against %user's friend list, removing existing friends and displaying only those connected by one degree from a current friend (not already on %user friend list)
it's linear social networking, not really dynamic, even though it may feel dynamic.
| Comment | File | Size | Author |
|---|---|---|---|
| #78 | 239162_user_relationships_people_you_might_know_78.patch | 4.6 KB | langworthy |
| #77 | 239162_user_relationships_people_you_might_know_77.patch | 0 bytes | langworthy |
| #35 | uymn.txt | 2.18 KB | icecreamyou |
| #26 | uymn.txt | 3.28 KB | icecreamyou |
| #23 | ur_blocks.module | 13.42 KB | icecreamyou |
Comments
Comment #1
zilla commentedsorry, that very last line of 3rd paragraph: user A sees a block saying 'people you might know: user B and User M (not C or F, those are one more node out)
Comment #2
sprsquish commentedMoving this to the more general -dev version.
I think more discussion will need to go in to this feature. For instance, how will relationship types weigh on how users know each other. I'm working on a site that uses UR for two differing relational ideas: friends and subscribers. Just cause someone is a subscriber doesn't mean they know each other in the way that I think you're talking about. So how do we provide the option to either forgo or at least devalue that relationship?
Comment #3
zilla commentedinteresting point. perhaps a top level stratification - when a user defines a "relationship type" it is either "intimate" or "removed" - in this case, a group is created like "family" or "friends" and a second level option is to note that the group type is "intimate" - user creates another group called "reviewers" (for a text for example) or "subscibers" (for a periodical, etc) and indicates "removed" (perhaps the wrong term for what i mean, but just not 'intimate' - at which point these other relationships (distal and on the connected nodes, etc) are either pegged to "all" or "intimate only" (by admin)
Comment #4
sprsquish commentedAs I think about this, I wonder if the Facebook approach might be more effective.
Users are given a list of people they may know because X number of their friends know them.
Alice: Bob, Cliff, Daniel
Bob: Alice, Frank, Gabe, Cliff
Cliff: Alice, Frank, Daniel
Daniel: Harold, Alice, Frank
Alice is friends with Bob, Cliff, and Daniel and all three of them are friends with Frank so it's likely Alice also knows Frank. Bob knows Alice and Cliff who both know Daniel, but the admin has required 3 connections before considering a match so the system wont display Daniel as a possible connection to Bob.
Relationship types can then be considered a weight. So if a set of connections are all of the same relationship type the number of needed connections would be lower than if they were all of a different type.
Alice:
Friends: Bob, Cliff
Coworkers: Daniel
Bob:
Friends: Alice, Cliff
Coworkers: Gabe, Frank
Cliff:
Friends: Alice, Bob
Coworkers: Daniel
Daniel:
Friends: Harold
Coworkers: Alice, Cliff, Frank
Here Daniel might know Bob through Alice and Cliff but because they're her Coworkers and Bob is a Friend of Alice and Cliff there's a lower likelihood of that connection than if Daniel was a Friend of Alice and Cliff.
We'd give the admin the ability to tune those weights. They could decided that 4 connections of the same type should be considered a possible match while 10 connections of differing types might be a match.
Comment #5
zilla commentedgood point - using a simple 1 degree with 2 or more points of intersection is easy and flexible - and giving admin controls might or might not be good - unfortunately most people don't really get into social network analysis and so may tend toward lower numbers in the hopes of 'growing a network' at the sacrifice of quality or integrity in implied relationships...but perhaps a simple ruleset exactly like what you describe: if user A has two or more friends (adjustable by admin, but no lower than 2 or 3) and those 2 friends have at least 1 (or more) friends in common - but not on user A list - then suggest to them...
Comment #6
ajayg commentedI think the purpose of this block is mainly for discoverability and not really deciding the strength of relationship a user need to establish with new users. That has to be determined by each user. e..g Alice just need to discover Bob has some relationship with Frank. What relationship Alice establishes with Frank is her decision and not based on the "type" of relationship between Bob and Frank. It might influence but is not the deciding factor.
So I think the weight etc is little overkill, it is nice to have but not necessary. All the block is saying " you might know" so if you find someone you already know, it is easier to add them to your network with whatver "level" of friendship you want to establish.
Comment #7
zilla commentedi hear you - and i suppose the overarching theme here is that aside from popsugar, fastcompany a handful of other sites, most users won't be dealing with hundreds of thousands or millions of users ;)
Comment #8
sprsquish commentedYou may be right. I'm probably getting ahead of myself here.
I do think we need a way for admins to dissociate specific types from the "you may know" list. Going back to my previous example, when "subscriber" and "friend" are both types "subscribers" should not be included in the list.
@ajayg The example above wasn't meant to limit possible friends to a specific type when they decide to actually become friends. It was only meant to say that groups of relationships under the same type should hold more weight than relationships crossing over types.
So... anyone know anything about social graphs and how to represent them in an RDBMS?
Comment #9
ajayg commentedI agree certain types of relationships should be disassociated with this block. One prime example would be "one way" relations where you are "fan" of someone doesn't make you a real friend of whoever you are admiring. Just felt weight etc is little overkills.
One way would be just give a list of roles (types) this will search on and admin can choose certain roles that would be used to
create the query, ignoring rest.
More Trees & Hierarchies in SQL
http://www.sqlteam.com/article/more-trees-hierarchies-in-sql
Specially look at the lineage concept at the end. These ideas depend on data manipulation at the time of storage because if you don't do at storage, compleletely doing a lookup is not scalable for larger data sets.
I think this will be great addition to UR because
1. It is done at the time of insertion of records so no issue with scalability
2. Provides a shortest path
3. Will allow to easily implement the above block.
Comment #10
sprsquish commentedSo my only issue with that site is that it's talking about Trees and Hierarchies. Those'll work fine for familial or organizational relationships, but friends are more of a web. Any tips for representing that?
Comment #11
ajayg commentedThink of this as multiple hierarchies. Each user has his/her own tree starting from him/her and he/she is part of someone elses tree. At some level say beyond 4 or 5 you become part of a big web. But In real life relationship beyond 4 th level are seldome useful for meaninful reference. I am thinking of model used by a very popular social networking site linkedin.com. They used to have 5 levels and reduced to 4 levels.
So you already have implmented a single root user to whom everybody is connected. So any user can have a lineage
/root/level1/level2/level3/level4 I haven't done the math but I suspect this itself can represent a billion users. So for all users in your tree (below your level) you go and find just how many people they are connected.
If the lineage is represented as a string as mentioned in the algorithm, One simple search shortcut would be (and I haven't thought through all implications) search for records which match say /root/level1/level2/*/level4/*
* is wild card. First * is level you are at etc
I must say I haven't completely thought through yet just writing as I am thinking openly.
Comment #12
sprsquish commentedI'm opposed to misrepresenting data. In this case the data isn't a hierarchy unless it is. It's really a graph and I think should be thought of and manipulated as such.
I found some interesting ideas here: http://www.artfulsoftware.com/mysqlbook/sampler/mysqled1ch20.html#nodes_...
The algorithms will need to be modified so that an update wont trigger an entire rewrite of the routes table. It's very late and my brain is very fried so I may need to go over all this info again tomorrow.
Comment #13
icecreamyou commentedI've been trying to do this without a module, just by creating a custom block; I think it can be done without creating extra tables.
[EDIT: I removed the rest of this post to make this page clearer, because there was a lot of (wrong) code.]
Comment #14
icecreamyou commentedAlright, that code was a little messy and none of it worked. Here's the first part, working, which displays a list of users with whom the current user and the user whose profile the current user is viewing have in common. I hard-coded the type of relationship in here: "Friends," and rtid = 2. I also hard-coded the website URL because I don't know enough about how to get it dynamically.
I'm working on the rest of it.
Comment #15
icecreamyou commentedOkay, here's what we've all been waiting for. It displays a list of users the current user might relate to, Facebook style. There are a few hard-coded values in here--check the code comments to change them.
This is intended to go in a block, but as the final comment says I recommend putting it in a block and adding a "[More]" link to a page.
Enjoy!
Comment #16
icecreamyou commentedOne more thing: I wrote this on D5, and haven't tested it on D6. It only works on MySQL (should be okay on 4 and 5) because of mysql_data_seek() but I'm not entirely convinced that that needs to be in there at all.
I'm not aware of any changes from D5 to D6 that would affect this, except maybe something in the UR tables that I wouldn't know about because I'm not using D6.
If the maintainers of UR don't want to put this into the module itself, I can look into contributing it as a separate module.
Comment #17
icecreamyou commentedComment #18
ajayg commentedI am getting following warning. I substituted ur.rtid with appropriate number.
Comment #19
icecreamyou commentedTry removing the mysql_data_seek() lines (on line 19 and 48, as the error you got notes) and see if that helps. I had never heard of any code in Drupal needing to use mysql_data_seek() before, but I was looking through some PHP documentation and it mentioned that it was necessary. It worked for me, so I left it in, but it's likely it's not needed at all.
Comment #20
icecreamyou commentedComment #21
ajayg commentedI removed the two mysql_data_seek() lines and it is working fine now as expected. I noticed a strange thing though. On user profile page it showed correct list of people I might know (friend of friends). But the same block shows a different list which were just direct friend on the other pages. So it is kind of odd to see direct friends as "people you might know". SO to work correctly the block needs to be disabled from pages other than profile pages.
Comment #22
icecreamyou commentedThat should never be the case with the "friends of friends" block. The code works completely independently of anything in the URL and doesn't depend on anything being on the page. I can't duplicate the experience you're having; the code even works fine for me if I put it in a page instead of a block.
The "mutual friends" block, however, should ONLY show up on profile pages that are not the user's own. To accomplish that, use this PHP in the Block Visibility field:
For the websites I'm using this code, I have the "friends of friends" block show up on the user's own profile, and the "mutual friends" block show up on other people's profiles.
Comment #23
icecreamyou commentedI'm attaching some code I started for a submodule that adds this capability (both the "users you might know" and the "mutual friends" blocks) but I don't have time to finish it. There's a note at the very beginning of the file that should help anyone who wants to work on this.
Remember that when you download the file, you need to change the extension from .module.txt back to .module.
Comment #24
icecreamyou commentedRelated (improved) code (though for FriendList, it uses essentially the same database structure; the only difference is the lack of an 'approved' column). May or may not work. Also lacks the benefits of the module, namely that there are no page views or settings.
Comment #25
asak commented@IceCreamYou: First - thank you!
I'm trying to use your comment from comment #15 but get this error:
Any idea?
I just went over the thread for FriendList and can see you guys have done some nice stuff.
Is there a chance you could backport your conclusions from there to the fix offered for UR here for all Drupal 5 users...?
Thanks again!
Comment #26
icecreamyou commentedI'm using this code on a production site. It's intended for a block, but (as you can tell from the final comment) it works just as well in a page.
Comment #27
zilla commentedwill this support d6 (@icecreamyou)? any changes that must be made?
Comment #28
icecreamyou commentedThere is no db_num_rows() function in D6, so just take that out.
Also, there's a bug (for D5 and D6): one of the variables was accidentally written with two dollar signs ($). Just search for $$ and replace it with $.
Remember that you should always test this kind of thing in a page before you put it in a block (you can just preview it, you don't have to save) because blocks can break your site if they malfunction.
Also note that with a lot of users this code gets very slow.
Comment #29
asak commentedTried the code you just posted but still getting the same error...
Should this work with UR 2.8/3-dev?
Comment #30
icecreamyou commentedI'm using 5.x-2.8. It's entirely possible that the DB structure changed in other versions, in which case I can't help you.
I know this has worked for other people though. System/install specs might help.
EDIT: I will say that it's probably better to group on u.uid than u.name.
EDIT 2: Just checked for sure, and that query is entirely valid MySQL. It should be valid on PGSQL as well.
Comment #31
asak commentedOk i'm using 2.8 too...
MySQL 4.1.22, PHP 5.2.6, Apache 2.2.9 (Unix)
I'm going to try this whole thing again and see what happens...
Comment #32
icecreamyou commentedAh. It probably doesn't work on MySQL 4. Try adding COUNT(uid) as a SELECT parameter - it may be that you have to explicitly declare a GROUP BY modifier function. If that doesn't work, I can't help you, unfortunately.
Try running the query directly from your database and see if you get a more specific error.
Comment #33
asak commentedI'll try to upgrade to mysql 5 ... it seems nothing is helping and i really need this feature!
Thanks for all the help!!!
EDIT: Well.. i'm afraid of upgrading mysql to 5.
Anyone know how to make this query work on mysql 4 ?
Comment #34
dummas_324324_32 commentedhow can I post the profile picture of any user im connected with, too?
Comment #35
icecreamyou commentedThe given code does that. But the attached code is better (and should work in 5.x and 6.x). It does require a little CSS theming to get it to look nice, however.
Comment #36
dummas_324324_32 commentedHi,
sry it does not work. It shows always the guest user... (in Drupal 6, User Relationships 6.x-1.0-beta10)
perhaps you can fix it.
you can alsp contact me for further informations
thx
mathias
Comment #37
icecreamyou commentedI can't guarantee it will work in 6.x because I have no idea if the DB has changed. I do know that it works in 5.x-2.x...
Comment #38
dummas_324324_32 commentedperhaps can you check it... and correct it ;-)
it will be nice if it works on d6
Comment #39
alex.k commentedQueries look good. There may be a number of issues, like Postgre vs MySQL, the type of relationship you are using (one way vs. two way), MySQL 4 vs. 5, as comments above discuss.
Comment #40
dummas_324324_32 commentedHi,
I use mysql 5.1 and two way relationship.
Comment #41
icecreamyou commentedI'm not the module maintainer and I have no interest in fixing it for a version that I know nothing about and don't use.
Comment #42
wkmit commented#36
Do you mean you see the anonymous user being returned?
I noticed that too.
When the number of results returned from the initial query is less than the $max number.
$z[$i] does not have a value. Therefore the code is loading a 'uid' that does not exist.
Adding...
if(count($user_rel_rel_com) < $max) {
$max = count($user_rel_rel_com);
}
..before the line of code
for ($i = 0; $i < $max; $i++) {
will help get rid of the anonymous users.
Comment #43
icecreamyou commentedThat's a valid solution for both branches actually--I didn't notice that bug before.
Comment #44
alex.k commentedPlease reopen if further support is needed, just cleaning up the issue queue.
Comment #45
icecreamyou commentedalex.k - this is a feature request, not a support request. If this isn't in the module yet, this issue should stay open until either it's added to the module or it's marked "won't fix." I'm leaving it closed since I'm not the maintainer.
Comment #46
sagar ramgade commentedHi People,
We really want to look forward to add this feature as friendlist already has it however as compared to user relationships it is still not integrated with various modules like activity, author pane.
If this feature is available in user relationships then i think this module will be awesome. We may also consider adding other feature of friendlist like followers, following etc in user realtionships.
I really love the user relatioship modulle andd would like to see it as all in one relationship module.
Could anyone please think of adding those feature in this.
Regards
Sagar
Comment #47
kvvnn commentedI also need this functionality.
I am trying to achieve it in Views, but have no luck with my combinations of filters / arguments / relationships.
Any help? Can Views_Or help me? Is the above code portable to d6?
EDIT : The functionality I am after is "Friends of this Friend"
Comment #48
dima700 commentedIceCreamYou, thank you.
Code in #15 worked for me in drupal 6. Also combination of #35 + #42 works.
It will be nice if this feature will be in the module.
Comment #49
alex.k commentedSounds like #35 + #42 is the way to go
Comment #50
dima700 commentedWe will be happy if it will be available soon.
Comment #51
Allisone commentedI feel kind of stupid (everybody seems to know what to do with that code),... but....
where do I have to put the php/uymn_0.txt code ? Views ? Some special place there ? Can't put it in a Block->Block Body, it only likes HTML. Or did you hard coded this stuff into a theme file ?!
Comment #52
Allisone commentedOK, I just found out, that I have to activate the PHP Filter Module to be able to add PHP code to a Block Body
Comment #53
dc1258 commentedI have been fiddling with this for a while and have a few questions that I hope someone can help me with.
First, is there a way to get this as a page? I am hoping to have a page which shows ONLY mutual friends and then can use filters to modify this page to show only "male", etc. If it were possible to make this into a filter that would be great too. Meaning that a user can filter "male" and then "mutual friends."
Second, when I display this as a block it shows the user's picture. How can I make it so it will only display the users name in the block?
Comment #54
dc1258 commentedI put the code into views using the View Custom Field Module but I don't have to much experience with creating php code. Can anyone help me finish off my site! The issues I have left are below:
-When the page displays it shows users 4 times in a list opposed to just once. I obviously would like users to only show up once.
-How can I get other profile fields to be displayed when this code is run? Right now it is just the user name and picture but how can I add a profile field such as "age?" Whenever I add anything like profile_age, etc it doesn't appear.
-How do you stop it from saying "more" after the query is run? I can't figure out how to get rid of it without corrupting the code!
Let me know if you can help me out!
Comment #55
mortenson commentedHow could you build a block with common friends? The same as facebook block.
I have tried with views but no success.
sorry if I am goign out of topic,
Thanks
Comment #56
apmsooner commented1st, you can set distinct option in views to limit to one listing per user.
2nd, I use the content profile module for setting up custom profile. In views, create a view of type node. Setup the user relationship fields like the user relationship browser default template but with argument set as requestee user, provide default argument (user id from url). Add field requestee user and any other custom fields setup in profile that you want to show. The view will work this way. One other thing I did was rewrote the output of the requestee field to display custom fields which looks like this [field_first_name_value] [field_last_name_value].
This way your view will show related users as: John Smith instead of jsmith (username). As far as setting up a view to show common friends like facebook... I havn't yet figured out how to do such a task but would love to know how if anyone has suggestions.
FYI, If view is setup as node, you can pretty much relate any fields and output as page, block, etc...
Comment #57
mortenson commentedok, any suggestions for building a common friends block?
Comment #58
dc1258 commentedThanks for the help but the "distinct" option didn't help with my php code. It still displayed the same information.
Also, your description for friends of friends doesn't display anything when I run a query. I have asked around and asked the module maintainer and it seems that, even with views, it is impossible to have a friend of a friend or people you might know block. If you have any other ideas let me know!
Comment #59
apmsooner commenteddc1258
I was partially answering your questions on #53 with my response. Seems as though you were wanting to draw out custom fields from the view so I provided an example of how to do that. Distinct works for me but perhaps I've set my view up differently then yours. Feel free to export your view and post it here and I'll see how you've got it setup. I did state that I didn't have a solution for "common friends" so my solution wasn't intended to answer that for you.
Comment #60
dc1258 commentedEveryone,
I am looking to pay to have the mutual friends block as well as a way to display friends of friends to users developed. Would anyone be interested in sharing the cost of development with me?
If so, please contact me.
Comment #61
okday commentedsubscribing
Comment #62
deltab commentedsubscribing
Comment #63
Ela commentedsubscribing
Comment #64
nonom commentedsubscribe
Comment #65
Donaldd commentedsubscribing
Comment #66
oxford-dev commentedsubscribe
Comment #67
rhymeswithcamera commentedsubscribe
Comment #68
igorik commentedsubscribe
Comment #69
troyl commentedAdding updated code, which you can put in a block, and it would give one a suggestion and will also show Add relationship request. Put the following code in a block, from add block page and make sure you have input filter as PHP
Comment #70
imDhaval commentedthanx for the updated code, it worked for me.
but it only shows user's friends of friends, however it's fine.
now i have a cck field named "City"
so what i want is to, show a common friends having same name of city(ex. NewYork)
as i am not php expert , so please help me how to add code for this in above #69 post.
plz help me
Comment #71
imDhaval commentedthis is a well implemented function of "people you might know"
unfortunately it is from friendlist module.,
but atleast it gives an idea how to implement this feature.
so anyone who convert this in user-relationship is most welcome.
Comment #72
glitz commentedThis is great, Thank you. Although I would like to theme the block a little buit better (No bullets, Imagecache presets, ect)
Anyway I can incorporate this into a views block? This way maybe I can get the feel of it looking better...
Comment #73
imDhaval commented@alex.k this is must wanted feature for this kind of module
like #71, the friendlist module implemented "people you might know" function.
when will you do that???
Comment #74
imDhaval commented@alex.k, and also marking as 1.x dev (might you want to intrested in implementing "people you might know" function)
Comment #75
igorik commented@imDahaval if it is so important for you, you can send the patch which will add this feature or to pay some programmer for doying this for you.
btw This feature was absolute unusable (wrong programmed) in Friendlist if you had more friends, it was too heavy for performance.
Comment #76
NathanM commentedSubscribing
Comment #77
langworthy commentedHere's a stub patch. It defines the new block for people you may know. This will only work on new installations of
user_relationshipsbecause of howdrupal_write_record()is used in_user_relationship_blocks_settings(). There is a stub update_N() hook in the .install file that will eventually fix this.There is no logic in the template file yet (i'm not sure about using a template for this but I'm just following the pattern with the other blocks).
I'm hoping someone lazier and smarter than me can use this to just start working on the problem now that some groundwork is laid. That being said I make no claim the groundwork is correct :)
I'm marking this as "Needs work" as this is only a starting place. I'm not sure if I should mark it as "Needs review".
Comment #78
langworthy commentedA patch with data would be nice.
Comment #79
rajesh1158 commentedHey troyl !!! cool script. works like a charm. super. i'm very happy. I was searching for a script(or a module) that can search for users' realnames(or the first name or last name) instead of their username(login name). I'm using realname module and finder module but both show only the username. can u help me??
Comment #80
mrf commentedSeeing what the test bot has to say about this patch.
Comment #82
allandk commentedsubscribe
Comment #83
mrf commentedClosed #692124: Adding a mutual friends block, #701692: UR common friends, and #1213190: Provide 'common friends' list as duplicates of this issue.
Comment #84
halloffame commentedIf there is a patch for D7 I will gladly volunteer to test it.
Comment #85
baff commentedsubscribe
Comment #86
kevstav13 commentedThe patch in #77 no longer exists. Clicking on it sends you to a blank page and it also says it's 0 bytes. Where can we find it?
Comment #87
mrf commented#78 should have the code mentioned in #77, but I haven't tested it
Comment #88
Sylense commented+1 for a D7 patch
Comment #89
mrf commentedI have been working this last year on a pluggable framework to provide this kind of information from multiple different data sources User Relationship Locator.
The initial implementation includes "friend of a friend" to an admin selectable degree, and there are plans to add in data from Facebook modules along with a few others to make this as accurate a listing as possible.
D7 users please come help test there, I'm going to wont-fix this issue since I don't see this making it into the main UR branch. If you are stuck on D6 I might listen to a sufficiently empassioned plea to backport the module once we release 1.0 for D7.
Comment #90
Sylense commented@mrf Great module! I am installing it on one of my D7 sites and will test it out
Comment #91
Originative commented#78: 239162_user_relationships_people_you_might_know_78.patch queued for re-testing.
Comment #92
mrf commentedNo code for this use is ever going to get committed. Either go with the solution in #89 or roll your own.
Comment #93
warmth commentedUser Relationship Locator is great feature if you wanna find new friends but how if you only wanna know the common friends between you (the authenticated user) and the profile you are visiting to?