Hide posts for non-members

Topics: Business Logic Layer
Jun 9, 2010 at 7:21 AM

I have a number of categories that I am only wanting certain users to see the postings for.  I have created a new role named "members" and am able to add users to it in the admin section.  How would I go about making certain categories and the posts in these categories only viewable by the users that are in the "members" role?  ie if the user is either not logged in (eg guest) or if the logged in user is not in the "members" role, they are not to see these posts or even the category in the archive page.

Is this possible?

Coordinator
Jun 9, 2010 at 11:07 AM
Edited Jun 9, 2010 at 11:10 AM

Here's one way to do it.  This could be improved so the member categories are not hard-coded, but are possibly a checkbox on the Categories page in the control panel.  This example requires modifying the Post.cs file in the BE core and re-compiling the core.

1.  Add this new code to Post.cs in the BE core.  Here the member categories are "Category 1" and "Category 2".

private static List<Category> _membersOnlyCategories;
private bool IsInCategoryAllowedByRole()
{
	if (this.Categories.Count == 0) { return true; }

	if (_membersOnlyCategories == null)
	{
		lock (_SyncRoot)
		{
			if (_membersOnlyCategories == null)
			{
				_membersOnlyCategories = new List<Category>();
				Category cat = null;

				cat = Category.Categories.Find(delegate(Category c) {
					return c.Title.Equals("Category 1",
					StringComparison.OrdinalIgnoreCase); });
				if (cat != null) { _membersOnlyCategories.Add(cat); }

				cat = Category.Categories.Find(delegate(Category c) {
					return c.Title.Equals("Category 2",
					StringComparison.OrdinalIgnoreCase); });
				if (cat != null) { _membersOnlyCategories.Add(cat); }
			}
		}
	}

	bool postContainsMembersOnlyCategory = false;
	foreach (Category c in _membersOnlyCategories)
	{
		if (this.Categories.Contains(c))
		{
			postContainsMembersOnlyCategory = true;
			break;
		}
	}

	if (postContainsMembersOnlyCategory)
	{
		if (Thread.CurrentPrincipal != null &&
			Thread.CurrentPrincipal.IsInRole("members"))
			return true;
		else
			return false;
	}

	return true;
}

2.  Replace the existing IsVisible and IsVisibleToPublic properties in Post.cs with these versions (that make use of the new code above).

public bool IsVisible
{
	get
	{
		if (IsAuthenticated || (IsPublished && DateCreated <=
			DateTime.Now.AddHours(BlogSettings.Instance.Timezone)))
			
			return IsInCategoryAllowedByRole();

		return false;
	}
}

public bool IsVisibleToPublic
{
	get
	{
		if (IsPublished && DateCreated <= DateTime.Now.AddHours(
			BlogSettings.Instance.Timezone))
			return IsInCategoryAllowedByRole();

		return false;
	}
}