Would it be possible to add another limit that can restrict the number of groups a user may join based on group content type? For example, I have a content type called "team" that is a group. I want to restrict users to be able to only join one (or any defined #) team. Is that something that would fit within this mod?

Comments

TechnoBuddhist’s picture

I was looking for this too, although I just to limit the number of groups joined regardless of content type. I might have to code it myself.

the sql is very simple, just got to figure out where to put it;

SELECT COUNT(nid) FROM `og_uid` WHERE uid=[user id]

TechnoBuddhist’s picture

A good place(?) to put it would somehow be on the view 'og' so that it limits the 'join' button to be displayed only if there is less than 'x' groups already joined.

Don't know views, spose it's time to learn.

TechnoBuddhist’s picture

I managed to do this by using a function in my theme template.php.

I'm sure there is a better way of doing this, but this works fine for me during my limited dev testing.

function zeropoint_views_view_field__og__page__subscribe($vars) {
  global $user;
  $result = db_query("SELECT COUNT(nid) as num FROM {og_uid} WHERE uid=%d",$user->uid);
  $num_grps = db_fetch_array($result);

   if ($num_grps['num'] < 3) {
    $group_nid = $vars->result[$vars->row_index]->nid;
    return "<a href=\"og/subscribe/" . $group_nid . "?destination=og\" rel=\"nofollow\" title=\"" . t('Join this group') . "\">". t('Join') . "</a>";


    // Alternative method for link creation seems longwinded and I don't see any benefit over the simple line above??
    /*
    $join_link = l(t('Join'),
			'og/subscribe/' . $group_nid, 
			array(
				'attributes' => array('rel' => 'nofollow', 'title' => t('Join this group')),
				'query' => '?destination=og'
				)
			);
    return $join_link; */
    }
    else {
      return "";
    }
}

If the user is a member of less than 3 groups then nothing is returned using 'return ""', otherwise the join link is returned.

I'm going to make '3' a theme specific variable changeable in my theme settings page.

There is a module that may work too if you don't wanna muck around in your template file; Views Custom Field module, it allows php code on views fields. I've got enough modules installed so I took this approach.

caschbre’s picture

If I understand that correctly your solution basically replaces the "Join" field on a groups view listing. Are there other places a user may join a group? For example, if they are on the group homepage isn't there a join link there as well?

TechnoBuddhist’s picture

You're absolutely correct! Good spot.

new code covers both places;

function zeropoint_views_view_field__og__page__subscribe($vars) {
	if (_can_join_group()) {
		$group_nid = $vars->result[$vars->row_index]->nid;
		return "<a href=\"og/subscribe/" . $group_nid . "?destination=og\" rel=\"nofollow\" title=\"" . t('Join this group') . "\">". t('Join') . "</a>";
	}
	else {
		return "";
	}
}

function zeropoint_item_list($vars) {
	if (_can_join_group()) {
		$group_nid = $vars->result[$vars->row_index]->nid;
		return "<a href=\"og/subscribe/" . $group_nid . "?destination=og\" rel=\"nofollow\" title=\"" . t('Join this group') . "\">". t('Join') . "</a>";
	}
	else {
		return "";
	}
}

function _can_join_group(){
  global $user;
  $result = db_query("SELECT COUNT(nid) as num FROM {og_uid} WHERE uid=%d",$user->uid);
  $num_grps = db_fetch_array($result);

  if ($num_grps['num'] < theme_get_setting('max_num_groups')) {
    return TRUE;
  }
  else {
    return FALSE;
  }
}

Notes

1. I've used my new theme setting variable 'theme_get_setting('max_num_groups')' instead of the literal number
2. I could have shortened the code by putting all the code in _can_join_group() but I decided not to, just in case of future mods to OG that I may want to copy. Doing it this way means I can have slightly different links in either place.
3. I'm using theme 'zeropoint' in case anybody didn't already catch it.

caschbre’s picture

Does the variable take into consideration the type of group? I use several different types of groups and would have different settings (or not setting) for certain types of groups.

TechnoBuddhist’s picture

No, not in my code it doesn't.

The variable is just the max number of groups that can be joined.

You'll need to change the SQL in _can_join_group() to take into account the type of group. If the type is available in $vars from each of the 2 calling functions, just pass it into _can_join_group().

To find out if the type is available, you need to print out the contents of $vars using the development module's dsm() function.

function zeropoint_views_view_field__og__page__subscribe($vars) {
  dsm($vars);
}
TechnoBuddhist’s picture

DOH!! Bad mistake... don't use the following function...

function zeropoint_item_list($vars) {
    if (_can_join_group()) {
        $group_nid = $vars->result[$vars->row_index]->nid;
        return "<a href=\"og/subscribe/" . $group_nid . "?destination=og\" rel=\"nofollow\" title=\"" . t('Join this group') . "\">". t('Join') . "</a>";
    }
    else {
        return "";
    }
}

This isn't the correct override. I thought something seemed too simple about it, _item_list isn't correct. Using this code you don't see the 'advanced help' and the Views 'theme information' lists due to the return "".

I'm looking for the correct override now, I don't wanna put logic into the block_og_0.tpl.php file which I assume would work, business logic in a template file just will not do!

I'll report back later.

TechnoBuddhist’s picture

It looks like the best/simplest/quickest(from cpu time perspective) is to add the following php code to the 'Group details' block(or just disable the block which is even easier).

<?php
 return _can_join_group();
?>

This should be added to the 'Show block on specific pages: ' with the 'Show if the following PHP code returns TRUE (PHP-mode, experts only).' radio selected.

This seems to be doing the job admirably!

caschbre’s picture

That looks like a great solution.

TechnoBuddhist’s picture

Another update...

Whilst testing I noticed that the above code displays a 'Join' link even for groups that the user is already a member of.

To fix this I now call some OG code 'og_is_group_member' and I don't use any sql calls at all now. Full code shown below...

function zeropoint_views_view_field__og__page__subscribe($vars) {
  $group_nid = $vars->result[$vars->row_index]->nid;

  if (_can_join_group($group_nid)) {
    $txt = t('Join');
    return l($txt, "og/subscribe/$group_nid", array('attributes' => array('rel' => 'nofollow', 'title'=>t('Join this group')), 'query' => drupal_get_destination()));
  }
  else {
    return '';
  }
}

function _can_join_group($group_nid){
  global $user;

  if (!isset($user->og_groups)) {
    $user = user_load(array('uid' => $user->uid));  
  }
	
  $num_grps = count($user->og_groups);

  if ($num_grps < theme_get_setting('eco_max_num_groups')) {
    return !og_is_group_member($group_nid, FALSE);
  }
  else {
    return FALSE;
  }
}

Note the link code is copied from some OG code...

return l($txt, "og/subscribe/$group_nid", array('attributes' => array('rel' => 'nofollow', 'title'=>t('Join this group')), 'query' => drupal_get_destination()));

The whole thing works much better now, doesn't require any sql and should be faster BUT.... it doesn't work with the 'Group details' block. In #9(above) I said to drop a call to _can_join_group() in the php code, obviously this doesn't work because we now need to pass a group_node_id to _can_join_group(). I don't know how to work out the current group id to pass, so I've just removed the block so it's not displayed at all.

caschbre’s picture

Hey Techno... I was going through the og.module file and came across the following function.

function og_subscribe_link($node) {
  if ($node->og_selective == OG_MODERATED) {
    $txt = t('Request membership');
  }
  elseif ($node->og_selective == OG_OPEN) {
    $txt = t('Join');
  }
  if(isset($txt))
    return l($txt, "og/subscribe/$node->nid", array('attributes' => array('rel' => 'nofollow'), 'query' => drupal_get_destination()));
}

Would it make more sense to override (is that the right word? preprocess? hook?) this function? That way we can continue to use all of the other og modules/submodules as they already are?

izmeez’s picture

subscribing

TechnoBuddhist’s picture

@caschbre.

Yes, you could use that function, I was going to! Sorry for not pointing that out, I was so focused on fixing my own issue that I forgot I should have mentioned it for other people. The function you found og_subscribe_link is where I got the line of code from for the link.

For my purposes I would rather have the 'title' attribute on the link than not have it. I could have changed the code in og_subscribe_link but that's just bad form and if it ever changed I'd need to reapply my hack.

My groups are open so I didn't need the check that og_subscribe_link does.

Hope you've got it sorted now.

bryancasler’s picture

I was happy to find this discussion because this is exactly what I am trying to do. Would anyone be willing to give me a step by step on how to get this working?

TechnoBuddhist’s picture

@animelion

3 things you need to do:

1. setup the max number of groups that can be joined
I use the zeropoint theme which allowed me to add the number as a variable that can be amended on the admin pages, I won't go into how to do it. It's not really necessary, once you set the max number you're probably not gonna wanna change it, certainly not very many times at all! So just change 'MAX_NUMBER_OG_GROUPS' in the code below.

2. You need to add the following 2 functions to the end of your sites/all/themes/[theme-name]/template.php file, making sure to change THEMENAME to the name of your theme

/**
 * These next 2 functions handle the max number of groups that can be joined
 * There is also a call to _can_join_group() in the 'Group details' block if used.
 * see issue http://drupal.org/node/589648
 */
function THEMENAME_views_view_field__og__page__subscribe($vars) {
  global $user;
  $group_nid = $vars->result[$vars->row_index]->nid;
  $return_link = '';

  // Tailor Message for Logged In User			
  if ($user->uid) {
    if (_can_join_group($group_nid,$user)) {
      $txt = t('Join');
      $return_link = l($txt, "og/subscribe/$group_nid", array('attributes' => array('rel' => 'nofollow', 'title'=>t('Join this group')), 'query' => drupal_get_destination()));
    }
  }

  // Tailor Message for Anonymous User
  else {
      $grp_link = "destination=og/subscribe/". drupal_get_path_alias($group_nid);
      $join = l('Login to join', "user/login", array('attributes' => array('rel' => 'nofollow', 'title'=>t('Login to join this group')), 'query' => $grp_link));
      $reg = l('Register to join', "user/register", array('attributes' => array('rel' => 'nofollow', 'title'=>t('Register to join this group')), 'query' => $grp_link));
      $return_link = $join . ' / ' . $reg;
  }	

  return $return_link;
}

// Change MAX_NUMBER_OG_GROUPS as required 
function _can_join_group($group_nid,$user){
  if (!isset($user->og_groups)) {
    $user = user_load(array('uid' => $user->uid));  
  }
  $num_grps = count($user->og_groups);

  if ($num_grps < MAX_NUMBER_OG_GROUPS) {
    return !og_is_group_member($group_nid, FALSE);
  }
  else {
    return FALSE;
  }
}

3. If you use the 'Group Details' block you need to add the following into the 'Page specific visibility settings', making sure you set 'Show if the following PHP code returns TRUE (PHP-mode, experts only).'

<?php
 return _can_join_group(); // in template.php
?>

That does the job.

Caveat - There may be other places that I've not found, because I don't use them, that may need to call _can_join_group().

Hope it helps.

bryancasler’s picture

Thanks for the response, before I go and do this I had 1 more question. Will this limit the max number of groups someone can join based per content type. Or just the max number of groups someone can join based on ALL content types?

ColdSun’s picture

Animelion:
The above sample looks to only set the max number of groups someone can join and does not take into consideration different content types

Golem07’s picture

@caschbre, anemelion

have you managed to combine the above solution with taking into account the content type? I am in dire need of this functionality, too.

caschbre’s picture

It wasn't a priority with the client so unfortunately I never did get around to it.