Hi,

I think I figured out how to create statuses with user relationships and have attached the exported view.

It includes 'All Statuses', 'Relationships Status' and 'My Status'.

It works if your relationship is called 'friend'.

Any suggestions to improve it would be most welcome ..

Comments

icecreamyou’s picture

Status: Active » Closed (works as designed)

FBSS cannot include default Views that (A) depend on other modules or especially (B) depend on special configurations in other modules. It's great that you got this working, and feel free to write a blog entry about how you did it or whatever, and maybe this will be useful to someone who's struggling with this task in the future; but it's not something that can be explicitly included in the module.

pribeh’s picture

Hey Liliplanet,

Have you successfully made a status view that displays both the user (being viewed) and his/her friends' statuses. So, one aggregated feed like on Twitter. I can come up with UR feeds like your "relationship" status but as soon as I put a "username" argument in their it won't show anything.

Thanks

liliplanet’s picture

Hi pribeh,

Sorry no, have not tried that. Maybe use a http://www.drupal.org/project/flag .. such a follow user? If you come right, let me know :)

Lilian

icecreamyou’s picture

StatusFileSize
new6.41 KB

I added this to the Facebook-style Statuses: Views documentation page, along with a sample view for Flag Friend (attached).

As far as getting a View of friends + you, that's certainly an issue related to friend modules and not FBSS. It does make sense that friend modules would have set it up this way, and it would take a special handler to build a query that would operate as you suggest because Views can't accept "OR" operations through its UI.

pribeh’s picture

Thanks Ice, I'm bringing up the issue with the Flag_Friend maintainers.

pribeh’s picture

Hey,

Apparently, Scott Reynolds says that with Activity 2.0 and Flag_friend this is possible by using "the filter Activiity: type > node and Activity Access: Flag Friend". I will test this tonight or tomorrow. As for User Relationships, Alex sent me to views_or, a module that provides a filter for ORing content in views but as I've just tested it doesn't provide a handler for facebook_statuse views just node views.

icecreamyou’s picture

Activity is certainly one way to put it all together. If you choose that route you can get any result you want from FBSS and any relationship module.

jalder’s picture

Friends + Me Status Feed (fbss, UR, views_or, and views 2):

patch facebook_status.views.inc by setting sid as the field of the base table, this is so distinct works correctly with the left joins we are about to introduce

patch views_or.views.inc to allow arguments when using facebook_status view

patch user_relationship_views.views.inc to allow a join of UR to facebook_status

Distinct: Yes

Relationships:
User relationships: Requestee user

Arguments:
Views Or: Begin alternatives
User relationships: Requester user (logged in user)
Views Or: Next alternative
User: Uid (logged in user)
Views Or: End alternatives

Resulting Query:
SELECT DISTINCT(facebook_status.sid) AS sid, facebook_status.pid AS facebook_status_pid, facebook_status.status AS facebook_status_status, facebook_status.status_time AS facebook_status_status_time, facebook_status.uid AS facebook_status_uid FROM facebook_status facebook_status LEFT JOIN user_relationships user_relationships ON facebook_status.uid = user_relationships.requestee_id LEFT JOIN users users_user_relationships ON user_relationships.requestee_id = users_user_relationships.uid LEFT JOIN users users ON facebook_status.uid = users.uid WHERE ((facebook_status.status) != ('')) AND ((user_relationships.requester_id = *****) OR (users.uid = *****)) GROUP BY sid ORDER BY facebook_status_status_time DESC

icecreamyou’s picture

sid is the field of the base table, at least in dev.

UR can probably be joined with FBSS using two relationships in a User view.

jalder’s picture

Ah, could be...

UR could be joined with FBSS using the User view, but then you run into the distinct issue on the fbss sid. I had issues with the left joins causing repeats of fbss posts, if views 2 adds the ability to set distinct on any gathered table column and not just the base table, this could alleviate the issue.

The frustrating thing I have with views is that I find myself writing out the sql query and then trying to reverse it into views.. which I don't think was in the intended use of the module.

dmetzcher’s picture

Re: Comment #4...

When I attempt to import the view included on the documentation page, I get the following errors. I am using Views 2. Any thoughts?

Filter handler facebook_status.pid_extra is not available.
Filter handler facebook_status.pid_extra is not available.
Filter handler facebook_status.pid_extra is not available.
Filter handler facebook_status.pid_extra is not available.
Filter handler facebook_status.pid_extra is not available.
Unable to import view.
icecreamyou’s picture

StatusFileSize
new17.06 KB

The filter was moved to pid_extra_2 to distinguish it more from the pid_extra field in the description. Try the attached view (I haven't tried it, but I just replaced "pid_extra" with "pid_extra_2" in the filter overrides, so it should work).

dmetzcher’s picture

Thank you, Ice. I appreciate you responding so quickly.
Please correct me if I'm wrong, but this view seems like it's intended to replace the existing "facebook_status" view that your module provides. Is that correct? Is the proper way to do this to (1) deactivate the original view and (2) import this view, or would you recommend simply modifying your view and adding whatever this view has to it?

icecreamyou’s picture

StatusFileSize
new17.08 KB

Oh, yeah, didn't notice that. Don't replace the original view, if you do it's a massive pain to upgrade. (In fact if you ever need to modify default views, you should always clone them first and make changes to the clone so there's no chance of losing your customizations when you upgrade.) The attached view has a different name so it won't try to overwrite the original.

However, do note that the attached view was generated from an old version of the facebook_status view. I don't think it has changed in any substantive way, but you might still be better off by building your own view (possibly from scratch) based on what you can learn from the attached view and the default views.

dmetzcher’s picture

Thanks, Ice. That's what I'm doing right now...I'm going to look at the Relationships tab and see what I can learn there and just duplicate it in my own, new view (facebook_status_relationships). I really only need a single page view that will show the logged in user's friends' statuses, so it sounds like a rather simple thing to do, given the example of this view you've provided. Appreciate the new, renamed view, though.

Also, on a side note, overriding views is something that's a bit fuzzy to me... I looked for documentation on the topic several times but couldn't really find anything. Can you tell me if, when one clones a view, (1) the name should remain the same as the original view (I have read that this is overriding the view), and (2) the original view should be deactivated?

dmetzcher’s picture

I think I've got a modified, working version of the view. I'm going to keep testing it and post the final result later in case anyone wants it.

icecreamyou’s picture

When you go to admin/build/views there are three kinds of views there: custom, default, and overridden. You start out with only default views. If you add your own by going to the "Add" tab then you create a custom view. And if you edit a default view, you've just overridden it. When you create a new view or clone an existing view you can't use the same name as an already-existing view (it just doesn't validate) so you are in effect creating a new custom view configured exactly like the original one.

Here's how you know the difference: on admin/build/view there are action links for each view. Default views have a link to either "enable" or "disable"; overridden views have a "revert" link; and custom views have a "delete" link.

dmetzcher’s picture

Thanks, Ice. That was an excellent explanation of Views overriding. I'm going to bookmark your comment for future reference. The documentation for Views should link to it as well. ;)

I'm attaching three views.

facebook_status_relationships - This is my modified version of the view provided earlier in this thread. I've modified a few things and changed the paths. I noticed that it was using paths like /status/%/friends, /status/%/mine, and /status/%/all. Since the view is only showing the statuses of the current logged in user and that user's friends (and another display that just shows everyone's statuses), I went with /statuses/my (for the logged in user), /statuses/friends (for the logged in user's friends), and /statuses/all (for everyone). This means that a standard menu can now use these paths (for example, I have /statuses/my linked to from the navigation menu.

facebook_status_recent - Overridden view that was provided by this module. I needed to remove the menu tab for recent statuses since it was appearing on the page that displayed the menu tabs for the facebook_status_relationships view. Other than that, no changes, really.

facebook_status_mentions - Overridden view that was provided by this module. Modified the layout a little. Added the user's picture to each status message. It looks just like facebook_status_relationships, and the menu tab that I also added appears on the page with the tab created by facebook_status_relationships. I also modified the "Facebook-style Statuses: Created time" field a little, adding a line break tag so that the Edit, Reply, Comment, etc. links are on a new line, as is the case with my facebook_status_relationships view above (I have also overridden the facebook_status view to do the same thing, so that things are consistent). I was going to just disable this view and add another display to the facebook_status_relationships view, but I decided to leave it in place and just override it (saving myself some time and making sure I can remember what's going on later).

Note that I added a CSS class to facebook_status_relationships and facebook_status_recent. In my stylesheet, I've added this:

/* Fix alignment of user picture when it appears in the table.
   Note that "views-status-updates-table" must be set as the CSS class
   for the view's display. */
.views-status-updates-table td.views-field-picture {
  vertical-align: top;
}

I noticed that the picture, when displayed in the table, wasn't at the top of the cell next to the original status update posted by that user. If there were comments on the status, it would appear in the middle of the cell. The class just makes sure that doesn't happen.

IceCreamYou: Please let me know if I've done anything that you think will cause issues (like overriding views, etc).

icecreamyou’s picture

dmetzcher, thanks for the detailed explanation and posting your views. I've linked to them from the documentation.

Nothing you've done should cause issues except that if the default views change you might want to revert them later to get the updates. That's why I recommend cloning them first and naming them something different instead of editing them directly. But if you're happy with what you've got, no real need to revert (unless the handlers change, which is very unlikely at this point). And of course if you ever feel like you need to revert a view, you can always clone your customized version, revert the original, and then compare that way.

dmetzcher’s picture

IceCreamYou: Any time. I really love this module, so I'm happy to help in any way that I can. :)

icecreamyou’s picture

I'm glad you're enjoying it.

jrivelli’s picture

dmetzcher, great views! Thank you! However, I have one question. I added your relationship view and it has about 5 displays or so in it. I select the view as the one where I want to have my friends only, but it only picks the default display. How do I make it select that display on the bottom of the list of displays that is the friends only one? Cheers!

icecreamyou’s picture

FBSS only uses the default display when you attach a view to a status update box. If you want a different configuration, create a new view with the same default settings as one of the existing displays.

jrivelli’s picture

Ah ok , Thanks Ice! Let's just hope I can match all the same settings properly :P

jrivelli’s picture

I utilized dmetzcher's view to display only friends status's. Is there a way to also include my own status's as well as my friends?

icecreamyou’s picture

I have a patch in the Flag Friend queue that allows that, but I have no idea whether UR can do it. Either way, that's a question for the UR queue.

jrivelli’s picture

Eh, not worth it. Haven't got a knowledgeable response out of the UR queue ever. I'll just deal with it until someone writes a patch for it.

dmetzcher’s picture

jrivelli: Sorry, I've been moving for several days and just got back to checking Drupal.org for updates to threads. Looks like Ice answered your question. I had the same question about displaying a user's own status updates along with those of his/her friends. Looks like it's not possible right now.

IceCreamYou: If we were to open a ticket in the UR queue, what should we ask for?

icecreamyou’s picture

@dmetzcher: "Is there a way to build a view that includes my own content as well as my friends' content?"

I just took a look at the code for the UR filter handlers and the answer as far as I can tell is no, it's not currently possible. Adding that ability is straightforward although not easy for someone (like me) who knows enough about Views handlers, and it's downright difficult for someone who doesn't. Basically it would require copying the query() implementation from the parent handler and adding a WHERE clause that says essentially "OR uid = " and then adding an option to control that. I don't have the time to write a patch.

jrivelli’s picture

Sounds fairly complex and not like its going to happen for some time. Oh well I guess. Perhaps in a few more releases of UR down the road.

hoporr’s picture

#29 @dmetzcher: "Is there a way to build a view that includes my own content as well as my friends' content?"
@IceCreamYou: "adding a WHERE clause that says essentially "OR uid = " and then adding an option to control that."

Below is a solution that solves this for current-user. It is possible to extend this into a general case, for any user.

First, you WILL need an or-clause in the View for this, but that’s not a problem: Views 3 now has that functionality out of the box (but as of this writing Views 3 is still in alpha), and for Views 2 you can install the Views-or module together with the patch from http://drupal.org/node/396340, #22 . Below, I’ll give a solution for Views-OR, but it can be easily adapted for Views 3.

I first tried to set up the or-clause by following the solution path outlined previously; but it only partially worked. I’ll describe this so that you can understand why I made the changes in the actual solution below.

At first, I tried setting up the view filters so that the query was for a) current_user’s friends OR b) current_user’s own statuses. Solutions to (a) and (b) were given above, so I thought this would be easy. Just like IceCreamYou said above, I set up a test for "OR uid = …" (using the filter: User = current_user).

And hat actually does work... but only as long as there is only one (!) relationship type: friends. As soon as you have multiple relationship types, (for example, “best-friends” implies “friends,” or “manager” implies “employee” ), the view query returns duplicate statuses. This is because a user can have entries in the users_relationship table for multiple types. Views has a DISTINCT setting, but in this case it only seems to work on the UID and not the statuses; so it won’t work as a solution.

So, the OR clause is a little bit more complicated. Basically, you would like the second or-clause to return the statuses by current_user without checking if current_user is in the user-relationship table (that is, the original solution in this thread for case (a) by itself). But because of the JOIN created by the view this is no longer possible in a simple way.

The solution I came up with is to rearrange the or-clause logic, so that they are mutually exclusive.

1. if current_user HAS entries in the user-relationship table.
  -> return all statuses by current-user and friends. There is an easy way to do this using existing View-filter:
    User relationships: Relationship type = friend
    User relationships: Requester or Requestee is current user = True
OR
2. if user HAS NO entries in the UR table. (Note: this means the first or-clause will return empty)
  -> return all statuses by user

(BTW, you may think that #1 solves the complete problem. It does so ONLY if every user has friend relationships. If a user does not, then this or-clause will not return any statuses even though the user may have some; and that’s why you need the second clause)

So what is missing is an additional views filter that does the check in #2: does a user have entries in the UR table? This can be done by either invoking a COUNT or an IN-set check in SQL, something like this (it returns 0/1, true/false).

SELECT ( (%d IN ( SELECT user_relationships.requestee_id FROM user_relationships WHERE user_relationships.approved = 1))
      OR (%d IN ( SELECT user_relationships.requester_id FROM user_relationships WHERE user_relationships.approved = 1)) );

Now that I explained the problem and outlined the solution, here are the details:

Here is my Views filter setup, using the Views-Or module mechanism. It should be trivial to change this to Views3’s OR mechanism.

Facebook-style Statuses: Status text != ‘’
Facebook-style Statuses: Not own statuses =  No
Views Or: Begin alternatives =
   User relationships: Relationship type = friend
   User relationships: Requester or Requestee is current user = True
Views Or: Next alternative =
   User: Current Yes
   User relationships: Does current user have relationships No
Views Or: End alternatives =

And here is the code that creates the new views filter handler. For this, I used the views_data_alter hook, so that I can add a new filter into the User-relationships group without having to hack that module. Arguable, this is something that should become part of the main user-relationships module; but I don’t think so.

(In the code below, I created a glue module called sq_ur_fbss; ur = User-relationships and fbss = Face Book Style Statuses. To change the code that follows for your module, do a global replace of this string . NOTE: the string does appear in the code as well ).

In your main glue module, turn on the views api:

/**
 * Implementation of hook_views_api().
 * 
 * This tells the system to load up the ...views.inc file, that holds all the views definition
 */
function sq_ur_fbss_views_api() {
    return array(
       'api' => 2,
       'path' => drupal_get_path('module', 'sq_ur_fbss'),
    );
}

Then create an views.inc file (mine is sq_ur_fbss.views.inc):

<?php

/* 
 * views_data_alter hook
 *
 * We are adding a handler into the "user-relationship" grouping
 */
function sq_ur_fbss_views_data_alter ( &$view )
{
   $view['user_relationships']['sq_ur_fbss_check_ur'] = array (
      'title'  => t('Does current user have relationships'),
      'help'   => t('Does current user have any relationships'),
      'filter' => array(
        'handler' => 'sq_ur_fbss_views_handler_filter_check_ur',
      ),
    );   
} 

/**
 * Implementation of hook_views_handlers().
 */
function sq_ur_fbss_views_handlers() {
   return array(
    'info' => array(
      'path' => drupal_get_path( 'module', 'sq_ur_fbss'),
    ),
    'handlers' => array(
      'sq_ur_fbss_views_handler_filter_check_ur' => array (
        'parent' => 'views_handler_filter_boolean_operator',
      ),
    ),
  );
}

Then create the actual filter file (mine is sq_ur_fbss_views_handler_filter_check_ur.inc)

<?php

/**
 * @file
 *   Filter to check if a user has any user-relationsips
 */

/**
 *  Filter class to check if a user has any user-relationsips 
 */
class sq_ur_fbss_views_handler_filter_check_ur extends views_handler_filter_boolean_operator {
  
  function construct() {
    $this->definition['type'] = 'yes-no';
    $this->definition['label'] = t("Determine if the current user has user-relationships");
    $this->value_value = $this->definition['label'];
    parent::construct();
  }

  function query() {
    $this->ensure_my_table();     // set table alias
    
    $theQuery = '';                // Set the query, depending on if check for YES (true)
    if ($this->value == true ) {   // or NO (false)
      $theQuery =   
      "( (%d IN ( SELECT $this->table_alias.requestee_id FROM $this->table_alias WHERE $this->table_alias.approved = 1))"
   ." OR (%d IN ( SELECT $this->table_alias.requester_id FROM $this->table_alias WHERE $this->table_alias.approved = 1)))"; 
    } else { 
      $theQuery =   
     "( (%d NOT IN ( SELECT $this->table_alias.requestee_id FROM $this->table_alias WHERE $this->table_alias.approved = 1))"
 ." AND (%d NOT IN ( SELECT $this->table_alias.requester_id FROM $this->table_alias WHERE $this->table_alias.approved = 1)))";
    }
    
    $theQuery = db_prefix_tables($theQuery);
    $this->query->add_where($this->options['group'], $theQuery, $GLOBALS['user']->uid, $GLOBALS['user']->uid);
  }
}

Initial tests shows that this is working.

If you want to generalize this solution to not be for the current-user ONLY, then you would have to change 1) this filter to check for an argument and 2) write another filter that takes the existing UR-filter “Requester or Requestee is current user = True” and makes it check for an argument as well.

icecreamyou’s picture

@hoporr, thanks for contributing! I'm sure this will be useful to others as well. I recommend that you submit a patch to User Relationships to add this filter as it's not FBSS-specific. (Also, in the future it makes it easier to read if you put long code blocks in attached files instead of writing them inline.)

pribeh’s picture

hoporr, that's an incredibly thorough explanation. I just might try and experiment with your approach sometime.

demonrage’s picture

@hoporr

hello, i managed to make a module out of ur code, it show in modules page, enable it, choose it from filters list.
but when i choose it it don't give me the yes/no selection, instead it says that the handler is broken.

any idea how to fix this??

demonrage’s picture

StatusFileSize
new1.83 KB

here is the module

demonrage’s picture

StatusFileSize
new1.83 KB

i have fixed the module and its here for everyone who want to use it.

demonrage’s picture

i discovered that this only happened when the looged in user is part of a relationship (someone write on his wall, or he attached some link). can somebody tell me how to solve this

AthenaAdam’s picture

Thanks friends for being so helpful. I tried hoporr's great suggestion that was wonderfully helpful. It was awesome. It showed me light after moving long in wilderness. I tried my best and succeeded replicating things. It worked for Current online users. But somehow I couldnt succeed in generalising it for all the friends - current as well as offline. I wish he could be as clear as in his rest of details when he said:
"If you want to generalize this solution to not be for the current-user ONLY, then you would have to change 1) this filter to check for an argument and 2) write another filter that takes the existing UR-filter “Requester or Requestee is current user = True” and makes it check for an argument as well."
With my limited ability I could not understand what kinda filter I shud add or substract in the original ones. Any help will be highly appreciated.

AthenaAdam’s picture

Sorry to bump, But using hoporr's recipe I get the same statuses of Current Users again and again - three or four duplicates. I tried to restrict that by Distint: yes. But it just removed all statuses. Anybody tried hoporr recipe successfully to show Statuses of Both Me and My Friends as shown on fb home page?

demonrage’s picture

@AthenaAdam

the same thing happens to me

sansui’s picture

I have also tried using hoporr's recipe without success. Statuses are duplicated in the view multiple times.

sansui’s picture

The filter: User relationships: Relationship type = Friend seems to be causing the duplicates for the logged in user's statuses. If a user has only one friend, their own statuses will show only once, but if they have more than one friend, it will display a status once for each friend.

AthenaAdam’s picture

Perhaps u r right, sansui. But removing that that filter User relationship: Friend doesnt remove duplicates. I tried many other permutations and combinations, but ended up in only increasing duplicates. Such a desperate situation and seems no help is at hand. alas!

sansui’s picture

Perhaps the easiest way to achieve what we want is through hook_views_query_alter(), and adding a "group by" statement to remove the dupes.

I'm not really sure what that group by statement would look like :P perhaps user id and status id.

sansui’s picture

Just did a quick experiment with this. I'm not too experienced with this kind of views manipulation, and it's been a long time since I had to do much with sql queries directly. Added this to my custom module (use your module instead of "mymodule"):

function mymodule_views_query_alter(&$view, &$query) {
  if ( $view->name == 'facebook_status_ur' ) {
     $query->add_groupby('users.uid, facebook_status.sid');
  }
}

I have not tested this extensively, but at the moment its showing what I expect to see. Only my 'friends' updates, and my updates (any posts on my 'wall' actually, not just from friends). The duplicates for current logged in user are gone.

Curious if Icecream or hoporr might have any comments on whether this is the right track? Don't want to steer others off course here

AthenaAdam’s picture

Hey Sansui u r gr8. Thanks a lot. Ur suggestion worked like a charm that removed all duplicates. I am really so thankful to u.

salientknight’s picture

Comments removed.

Sorry missed this in an earlier thread.
Thank you.

salientknight’s picture

I am really close to getting this to work... I get User + Friends with no duplicates (thanks to Sansui's code) but I cannot get it to filter out "Non-friends" In other words all users are showing up.

Any help would be great!

Thank you

I have views 3 and the following settings.

Relationships
User relationships: Requestee user
User relationships: Requester user

Sort criteria
Facebook-style Statuses: Created time desc
Facebook-style Statuses: Status ID desc

Filters
(
Facebook-style Micropublisher: Do not show empty status Yes
AND Facebook-style Statuses: Only own statuses Yes
) AND (
User relationships: Relationship type = friend
OR User: Current Yes
)

salientknight’s picture

Ok I got it! Using Views 3

(
Facebook-style Statuses: Status text !=
AND Facebook-style Statuses: Not own statuses No
) AND (
User relationships: Relationship type = friend
OR User relationships: Requester or Requestee is current user True
)

I also use the code from Sansui to filter out duplicates:

<?php
function mymodule_views_query_alter(&$view, &$query) {
  if ( $view->name == 'facebook_status_ur' ) {
     $query->add_groupby('users.uid, facebook_status.sid');
  }
}
?>

This combination gives me 1) User statuses 2) Friends statuses 3) No one else. 4)No Duplicates

Hope this helps someone else....

phantomvish’s picture

subscribing

icecreamyou’s picture

Status: Closed (works as designed) » Closed (fixed)

I just committed a default UR view to dev that shows the status updates of an argument user and that user's friends. The view only shows up if UR is enabled. I also added the ability to use different views for a user's own status stream and other users' status streams. If UR is enabled, the default is to use the UR view for users' own streams and facebook_status_stream for other users' streams. (If you've already saved your context settings at any point, the defaults won't affect you.)

demonrage’s picture

@IceCreamYou

does this view you committed in dev support more than one user relation type (Friends - coworkers - colleges and so ......) or just one user relationship type ??

Thanks in advance

icecreamyou’s picture

You could just try it... also since it's Views, it's easy to change if you don't like how it's set up.

But the answer is that it's not tied to any relationship type by default. (It couldn't possibly be; that would require the same relationship type to exist on every site, which is obviously not the case.)