+1-888-365-2779
Try Now
More in this section
Categories
Bloggers
Blogs RSS feed

Implement Forum subscription in Sitefinity 3.x

by Ivan Dimitrov
In this post I will show you how you can implement Forum subscription in Sitefinity. Instead of going each time to a given post you can just subscribe to the forum post and receive email notification once someone reply to you or you just want to stay informed about the progress of a post.

 

1. I created a database table where I will persist the subscriber - threadID data. You can use the code below to create the same table at your end.

SET ANSI_NULLS ON 
GO 
 
SET QUOTED_IDENTIFIER ON 
GO 
 
CREATE TABLE [dbo].[ForumSubscribers]( 
    [ThreadID] [uniqueidentifier] NOT NULL
    [UserID] [uniqueidentifier] NOT NULL
    [UserEmail] [nvarchar](50) NOT NULL
 CONSTRAINT [PK_ForumSubscribers] PRIMARY KEY CLUSTERED  
    [ThreadID] ASC
    [UserID] ASC 
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ONON [PRIMARY
ON [PRIMARY
 
GO 
 

2. I created a simple LINQ-SQL class called ForumSubscriptionDataContext

3. I modified templates below.

 ~/Sitefinity/ControlTemplates/Forums/SingleThread.ascx - this template list all post in a thread. Here I will add "subscribe" and unsubscribe links.

 

    <div class="sf_threadTitle"
        <h1><asp:Literal runat="server" ID="threadTitle"></asp:Literal></h1
        <asp:LinkButton ID="deleteThreadButton" runat="server" Text="<%$Resources:DeleteThread %>"></asp:LinkButton> 
       <asp:LinkButton ID="subscribeBtn" runat="server" Text="Subscribe to this thread" ></asp:LinkButton> 
       <asp:LinkButton ID="UnSubscribeBtn" runat="server" Text="UnSubscribe to this thread" ></asp:LinkButton> 
    </div> 

 

Now I have to create a code behind of this template and subscribe for Click event of each link, so that I can execute our logic.

- Page_Load - subscribe for click events of our buttons.

- OnPreRender - here I am getting the thread ID from the QueryString. ForumSubscriptionDataContext class  is used to manage the data from my custom tablet. Here OnPreRender I check whethet the current user is subscribed to this thread or not and show/hide Sibscribe and Unsibscribe links.

- UnSubscribeBtn_Click - remove the user from the datasource

- subscribeBtn_Click - add new subscriber to the datasource

 

public partial class Sitefinity_ControlTemplates_Forums_SingleThread : System.Web.UI.UserControl 
    public void Page_Load(object sender, EventArgs e) 
    { 
        // subscribe for click events of our buttons 
        this.subscribeBtn.Click += new EventHandler(subscribeBtn_Click); 
        this.UnSubscribeBtn.Click += new EventHandler(UnSubscribeBtn_Click); 
    } 
 
    // Here we have to check whether the user is subscribed to the forum or not  
    // and hide or show - subscribe and unsubscribe links 
    protected override void OnPreRender(EventArgs e) 
    { 
        base.OnPreRender(e); 
        if (!String.IsNullOrEmpty(HttpContext.Current.Request.QueryString["mode"]) && !String.IsNullOrEmpty(HttpContext.Current.Request.QueryString["thread"])) 
        { 
            Guid ThreadID = new Guid(HttpContext.Current.Request.QueryString["thread"].ToString()); 
            ForumSubscriptionDataContext dataContext = new ForumSubscriptionDataContext(); 
            //we are sure that this query it will only result in one record - the current user email. So we use  
            // SingleOrDefault(); Returns the only element of a sequence, or a default value if the sequence is empty; 
            //this method throws an exception if there is more than one element in the sequence. 
            var query = (from sub in dataContext.ForumSubscribers 
                         where sub.ThreadID == ThreadID 
                         select sub.UserEmail).SingleOrDefault(); 
            if (query != null
            { 
                subscribeBtn.Visible = false
                UnSubscribeBtn.Visible = true
            } 
            else 
            { 
                subscribeBtn.Visible = true
                UnSubscribeBtn.Visible = false
 
            } 
        } 
    } 
    /// <summary> 
    /// remove an user from the database 
    /// </summary> 
    /// <param name="sender"></param> 
    /// <param name="e"></param> 
    void UnSubscribeBtn_Click(object sender, EventArgs e) 
    { 
        Guid ThreadID = new Guid(HttpContext.Current.Request.QueryString["thread"].ToString()); 
        string uName = Telerik.Security.UserManager.GetCurrentUserName(); 
        MembershipUser user = Membership.GetUser(uName); 
        Guid userID = new Guid(user.ProviderUserKey.ToString()); 
        string eMail = user.Email; 
        ForumSubscriptionDataContext dataContext = new ForumSubscriptionDataContext(); 
        var query = from sub in dataContext.ForumSubscribers 
                    where sub.ThreadID == ThreadID && sub.UserID == userID 
                    select sub; 
        var record = query.First<ForumSubscriber>(); 
        dataContext.ForumSubscribers.DeleteOnSubmit(record); 
        dataContext.SubmitChanges(); 
        subscriptionMessage.Text = "<span style=background-color:Red;>YOU HAVE BEEN SUCCESSFULLY UNSUBSCRIBED</span>"
    } 
    /// <summary> 
    /// add user to the datbase 
    /// </summary> 
    /// <param name="sender"></param> 
    /// <param name="e"></param> 
    void subscribeBtn_Click(object sender, EventArgs e) 
    { 
        if (!String.IsNullOrEmpty(HttpContext.Current.Request.QueryString["mode"]) && !String.IsNullOrEmpty(HttpContext.Current.Request.QueryString["thread"])) 
        { 
            // get the thread ID. 
            Guid ThreadID = new Guid(HttpContext.Current.Request.QueryString["thread"].ToString()); 
            string uName = Telerik.Security.UserManager.GetCurrentUserName(); 
            MembershipUser user = Membership.GetUser(uName); 
            Guid userID = new Guid(user.ProviderUserKey.ToString()); 
            string eMail = user.Email; 
            // subscribe this user  
            ForumSubscriptionDataContext dataContext = new ForumSubscriptionDataContext(); 
            ForumSubscriber newSubscriber = new ForumSubscriber(); 
            newSubscriber.ThreadID = ThreadID; 
            newSubscriber.UserID = userID; 
            newSubscriber.UserEmail = eMail; 
            dataContext.ForumSubscribers.InsertOnSubmit(newSubscriber); 
            dataContext.SubmitChanges(); 
            subscriptionMessage.Text = "<span style=background-color:Green;>YOU HAVE BEEN SUCCESSFULLY SUBSCRIBED</span>"
        } 
    } 
 

 

 ~/Sitefinity/ControlTemplates/Forums/EditPost.ascx -  I use this template to get the newly added content and all previous posts and send an emil to the subscribed user. Here I created a code behind of the template and on Page_Load I subscribed for save button click.

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Data.Linq; 
using System.Web; 
using System.Web.UI; 
using System.Web.UI.WebControls; 
using Telerik.Forums.WebControls; 
using Telerik.Forums; 
using Telerik.Security; 
using System.Web.Security; 
using Telerik.Web.UI; 
using System.Net.Mail; 
using System.Collections; 
using Telerik.Forums.Data; 
 
public partial class Sitefinity_ControlTemplates_Forums_EditPost : System.Web.UI.UserControl 
    protected void Page_Load(object sender, EventArgs e) 
    { 
        this.saveButton.Click += new EventHandler(saveButton_Click); 
    } 
 
    void saveButton_Click(object sender, EventArgs e) 
    { 
        if (!String.IsNullOrEmpty(HttpContext.Current.Request.QueryString["mode"]) && !String.IsNullOrEmpty(HttpContext.Current.Request.QueryString["thread"])) 
        { 
            // get the thread ID. 
            Guid ThreadID = new Guid(HttpContext.Current.Request.QueryString["thread"].ToString()); 
            ForumSubscriptionDataContext dataContext = new ForumSubscriptionDataContext(); 
            string uri = HttpContext.Current.Request.Url.ToString(); 
            // get our subscriber 
            var query = from sub in dataContext.ForumSubscribers 
                        where sub.ThreadID == ThreadID 
                        select sub.UserEmail; 
            // send email to our subscriber that there is a new post 
            foreach (var email in query) 
            { 
                MailMessage message = new MailMessage("yourhost@here.com", email); 
                message.IsBodyHtml = true
                message.Body = "<b>ThreadConversation</b>:" + tbQuote.Content + "<b>LastReply is:</b>" + editor.Content + "<br />" + "<i>Click the link below to reply</i>" + "<p>" + uri; 
                message.From = new MailAddress("yourhost@here.com"); 
                message.Sender = new MailAddress("yourhost@here.com"); 
                SmtpClient client = new SmtpClient(); 
                client.Send(message); 
            } 
            dataContext.Dispose(); 
        } 
    } 
 

10 comments

Leave a comment
  1. SaQ Jan 01, 2010
    well.. its really good.
    but in sitefinity version i am using, 3.7
    there is no "threadID" in the querystring... :-(
    what should i do??
  2. Ivan Dimitrov Jan 13, 2010
    I get back to you in our forums where you opened a request
  3. Jay Sep 27, 2010
    Could you post a link to that forum thread?  I'm interested in this as well.

    Great write up.  Thanks!
  4. tarun Oct 28, 2010
    Where was this request opened?
  5. tarun Oct 28, 2010
    Where was this request opened?
  6. tarun Oct 28, 2010
    Where was this request opened?
  7. tarun Oct 28, 2010
    oh..great I just refreshed this page and comment adds again and again.
  8. tarun Oct 28, 2010
    oh..great I just refreshed this page and comment adds again and again.
  9. tarun Oct 28, 2010
    oh..great I just refreshed this page and comment adds again and again.
  10. sathi Dec 17, 2010
    The code works fine for me I have just follow the exact steps described by this tallanted person and was able to insert, update and delete.
    Dog Boots

    Leave a comment