Differentiate Owner, Member, Visitor

Jan 25, 2011 at 3:16 PM

Our company makes extensive use of team sites.

On our Team Site Landing page, I wrote a web part called "My Teams" which lists all of the Team Sites the user can access.

It works great, code is below. Looks like discussion won't allow me to add a screen shot.

<script type="text/javascript" src="https://team.gsk.com/Javascript/jquery-prod.js"></script>
<script type="text/javascript" src="https://team.gsk.com/Javascript/jquery.SPServices-prod.js"></script>
<script type="text/javascript">
	var ERROR_MSG = 'This web part has encountered a problem.<br/>Please try again by refreshing the page.<br/>'
				  + 'If the problem persists, please call your local Help Desk.';
	var queryXml = '<QueryPacket xmlns="urn:Microsoft.Search.Query" Revision="1000">'
				 + '<Query domain="QDomain">'
				 + '<SupportedFormats><Format>urn:Microsoft.Search.Response.Document:Document</Format></SupportedFormats>'
				 + '<Context>'
				 + '<QueryText type="STRING" language="en-US">SCOPE:"TeamSitesScope" ContentClass:"STS_Site"</QueryText>'
				 + '</Context>'
				 + '<SortByProperties><SortByProperty name="Title" direction="Ascending" order="1"/></SortByProperties>'
				 + '<Range><StartAt>1</StartAt><Count>100</Count></Range>'
				 + '</Query>'
				 + '</QueryPacket>';

$(document).ready(function(){
	function displayErrorMessage() {
		$("#MemberMsg").html(ERROR_MSG);
	}
	
	function populateLinks(names, hrefs) {
		var count = names.length;
		if (count == 0) {
			$("#MemberMsg").html("You are not a member of any GSK Teamsites.");
		} else if (count <= 6) {
			if (count == 1) {
				$("#MemberMsg").html("You are a member of one GSK Teamsite.");
			} else {
				$("#MemberMsg").html("You are a member of " + count + " GSK Teamsites.");
			}
			for (var i=0; i<count; i++) {
				var link = '<a href="' + hrefs[i] + '">' + names[i] + '</a>';
				$("#LeftList").append('<li style="line-height:20px;">' + link + '</li>');
			}
			$("#LinksList").show();
		} else {
			$("#MemberMsg").html("You are a member of " + count + " GSK Teamsites.");
			var half = Math.round(count/2);
			for (var i=0; i<half; i++) {
				var link = '<a href="' + hrefs[i] + '">' + names[i] + '</a>';
				$("#LeftList").append('<li style="line-height:20px;">' + link + '</li>');
				if (i+half < count) {
					link = '<a href="' + hrefs[i+half] + '">' + names[i+half] + '</a>';
					$("#RightList").append('<li style="line-height:20px;">' + link + '</li>');
				}
			}
			$("#LinksList").show();
		}
	}
	
	$().SPServices({
		operation: "Query",
		async: false,
		queryXml: queryXml,
		debug: true,
		completefunc: function (xData, Status) {
			if (Status != "success") {
				displayErrorMesssage();
				return;
			}
			var queryResult = $(xData.responseXML).find("QueryResult").text();
			var xml = $("<xml>" + queryResult + "</xml>");
			var queryStatus = xml.find("Status").text();
			if (queryStatus != "SUCCESS") {
				displayErrorMesssage();
				return;
			}
			var countStr = xml.find("Count").text();
            if (countStr.length == 0)
                countStr = '0';
            var count = parseInt(countStr);
			var titles = new Array(count);
			var paths = new Array(count);
            if (count > 0) {
				var cnt = 0;
				xml.find("Document").each(function () {
					titles[cnt] = $("Title", $(this)).text();			
					paths[cnt] = $("Action>LinkUrl", $(this)).text();
					cnt++;
				});
            }
			populateLinks(titles, paths);			
		}
	});
});
</script>
 
<table border="0">
	<tr style="height:5px;"></tr>
	<tr>
		<td id="MemberMsg" style="text-align:center;"></td>
	</tr>
	<tr style="height:10px;"></tr>
	<tr>
		<td>
			<div id="LinksList" style="display:none">
			<table style="border:1px solid #bcaaa7;" cellspacing="10px">
				<tr>
					<td style="vertical-align:top;"><ul id="LeftList" style="list-style-type:square;color:#a88a86;margin-right:0px;"></ul></td>
					<td style="vertical-align:top;"><ul id="RightList" style="list-style-type:square;color:#a88a86;margin-right:5px;"></ul></td>
				</tr>
			</table>
			</div>
		</td>
	</tr>
</table>

The users would like the output separated into 3 lists; Owner, Member, and Visitor.

Seems like such a reasonable request ;-}.

HOWEVER, I am not sure how to proceed. IFIFIFIF I understand it, "GetUserMemberships" isn't going to give me this breakout.

Can you point me in the right direction?  Which functions/methods will allow me to create these 3 lists???

In advance, THANKS!!! This is a GREAT library!  We live in the BPOS environment, and so everything we can do client-side is a blessing!

Cheers,
S~

Jan 26, 2011 at 7:16 PM

Hi S,

When you know the exact groupnames of the sites you can use the operation 'GetUserCollectionFromGroup' and check if the currentuser is present in the returned xml.
Based on this the teamsite can be pushed to one of the Owner, Member or Visitor lists.

This is a very basic example:

    $().ready(function () {
        var alreadyProcessed = false;
        $().SPServices({
            operation: "GetUserCollectionFromGroup",
            groupName: "YourGroupNameHere",
            completefunc: function (xData, Status) {
                $("#results").text(xData.responseXML.xml);
                $(xData.responseXML).find("User").each(function () {
                    var userName = $(this).attr("LoginName");
                    var currentUser = $().SPServices.SPGetCurrentUser();

                    if (currentUser == userName) {
                        $("#user").text("IN GROUP: " + currentUser);
                        alreadyProcessed = true;
                    }
                    else if(!alreadyProcessed){
                        $("#user").text("** NOT IN GROUP: " + currentUser + " **");
                    }
                });
            }
        });
    });

Maybe it's an option to use jQuery templates to format the three lists in stead of building the html you showed in the example above.

I hope this points you in a direction you can work with.

Regards, Anita

Jan 26, 2011 at 7:27 PM

Hi S,

Well, it may be better and faster to use:

 $().ready(function () {
        $().SPServices({
            operation: "GetGroupCollectionFromUser",
            userLoginName: $().SPServices.SPGetCurrentUser(),
            async: false,
            completefunc: function (xData, Status) {
                $("#results").text(xData.responseXML.xml);
            }
        });
    });

Regards, Anita

Jan 27, 2011 at 4:00 PM

OK....crawl, walk, run, fly!
We have maybe 1000 teamsites today.
The goal of the web  part on the landing page is to give users the subset of teamsites they can "see", broken up into the three lists (Owner, Member, Visitor).

Are you suggesting that I do one query to get the list of teamsites, and then one query EACH to see what status the user has?

Not trying to be dense :((. Just don't envision the solution yet. The "GetGroupCollectionFromUser" operation assumes current site.

Is it possible to nest jQuery calls?

As I said, not trying to "try your patience" - I just don't get it yet...

Thanks!

Jan 27, 2011 at 4:32 PM

Hi S,

You certainly have a lot of sites, indeed!

The GetGroupCollectionFromUser gets all the groups the user is a member of at once within the current site collection(incl subsites).
The result of the function gives you a list (well, xml) with all the group names.

Maybe you have some kind of naming convention for the usergroups like ´<siteTitle> <owner/member/visitor>' so you can match the team site name from the query with a part of the groupname and get the owner/member/visitor of the matching groupname.
So you don't have to query each teamsite for the user, but you have to query the current users' groups once(if in the same site collection) and match them on your list of teamsites from the first query.

Does this make sense?

Regards, Anita

 

Jan 27, 2011 at 5:12 PM

My bad & thanks for your quick response!

Let me better define our situation.
For ease of management (permissions + capacity), each teamsite is a separate site collection.

The web "https://team.gsk.com" has a landing page "https://team.gsk.com/pages/teamlanding.aspx". That's where my web part lives.
Each teamsite is a separate site collection, with a URL that looks like "https://team.gsk.com/sites/TeamSiteName/default.aspx".

The query in my first post uses Search, but it does return the titles and urls for all of the site collections that the current user has at least VISITOR permissions.
If there is a better way to get that list, I'm all for it. Still, I only have a list in my hands, which doesn't give me the differentiation I need. I was hoping to make only one web service
call so the web part would execute quickly. I don't see anything in the set of web service calls that does what I need, but I may have lost the plot.
I have also never done more than one .SPServices() call in a web part, so I don't know if this is the right approach.

The user request just seems so darn reasonable, I ought to be able to make it happen.

Lower in the priority list, I'll gladly try jQuery templates once I get the hard bits done!

Cheers,
S~

Jan 28, 2011 at 7:41 AM

Hello,

Below i give you my webpart, they show all groups of the current site :

<script type="text/javascript" src="/JavascriptLibrary/jquery-1.4.min.js"></script>
<script type="text/javascript" src="/JavascriptLibrary/jquery.SPServices-0.5.4.min.js"></script>

<script type="text/javascript">

	function liensPermissions() {
	
		$().SPServices({
			operation:  "GetPermissionCollection",
			objectName: $().SPServices.SPGetCurrentSite(),
			objectType: "Web",
			completefunc:  function(xData, Status) {	
				$("#lienPermissions").html("");
				  $(xData.responseXML).find("Permission").each(function(){
						$("#lienPermissions").append("<a href='~/../../_layouts/people.aspx?MembershipGroupId=" + $(this).attr("MemberID") + "'>" + $(this).attr("GroupName") + "</a><br/>");
                  });
			}
		});	
	}

    _spBodyOnLoadFunctionNames.push("liensPermissions");


</script>
<div id="lienPermissions"></div>



See U,

Daxuza

Jan 28, 2011 at 9:18 AM

Hi S,

Well, I agree that the user request is reasonable, but in the mean time I'm pulling my hair out for a performance-wise nice solution...

Maybe client side is not the best option, so I fired Visual Studio and did some C# programming.
The only solution I came up is to loop the site collections and check if the current user is member of the associated visitor/member/owner groups. But I don't know how this will perform with over 1000 sites, because it still has to check this for every site collection.

I really can't think of another solution...

Regards, Anita