PageRenderTime 18ms CodeModel.GetById 1ms app.highlight 12ms RepoModel.GetById 1ms app.codeStats 0ms

/BlogEngine/BlogEngine.NET/App_Code/Controls/RecentComments.cs

#
C# | 225 lines | 148 code | 39 blank | 38 comment | 15 complexity | 7a1c42f48dab3a51f4f8239e42e6ca25 MD5 | raw file
  1// --------------------------------------------------------------------------------------------------------------------
  2// <summary>
  3//   Builds a category list.
  4// </summary>
  5// --------------------------------------------------------------------------------------------------------------------
  6
  7namespace App_Code.Controls
  8{
  9    using System;
 10    using System.Collections.Generic;
 11    using System.IO;
 12    using System.Linq;
 13    using System.Text.RegularExpressions;
 14    using System.Web.UI;
 15    using System.Web.UI.HtmlControls;
 16
 17    using BlogEngine.Core;
 18
 19    using Resources;
 20
 21    /// <summary>
 22    /// Builds a category list.
 23    /// </summary>
 24    public class RecentComments : Control
 25    {
 26        #region Constants and Fields
 27
 28        /// <summary>
 29        /// The sync root.
 30        /// </summary>
 31        private static readonly object syncRoot = new object();
 32
 33        /// <summary>
 34        /// The comments.
 35        /// </summary>
 36        private static readonly Dictionary<Guid, List<Comment>> blogsComments = new Dictionary<Guid, List<Comment>>();
 37
 38        #endregion
 39
 40        #region Constructors and Destructors
 41
 42        /// <summary>
 43        /// Initializes static members of the <see cref="RecentComments"/> class.
 44        /// </summary>
 45        static RecentComments()
 46        {
 47            BindComments();
 48            Post.CommentAdded += (sender, args) => BindComments();
 49            Post.CommentRemoved += (sender, args) => BindComments();
 50            Post.Saved += PostSaved;
 51            Comment.Approved += (sender, args) => BindComments();
 52            BlogSettings.Changed += (sender, args) => BindComments();
 53        }
 54
 55        #endregion
 56
 57        #region Properties
 58
 59        private static List<Comment> Comments
 60        {
 61            get
 62            {
 63                Guid blogId = Blog.CurrentInstance.Id;
 64
 65                if (!blogsComments.ContainsKey(blogId))
 66                {
 67                    lock (syncRoot)
 68                    {
 69                        if (!blogsComments.ContainsKey(blogId))
 70                        {
 71                            blogsComments[blogId] = new List<Comment>();
 72                        }
 73                    }
 74                }
 75
 76                return blogsComments[blogId];
 77            }
 78        }
 79
 80        #endregion
 81
 82        #region Public Methods
 83
 84        /// <summary>
 85        /// Outputs server control content to a provided <see cref="T:System.Web.UI.HtmlTextWriter"/> object and stores tracing information about the control if tracing is enabled.
 86        /// </summary>
 87        /// <param name="writer">The <see cref="T:System.Web.UI.HtmlTextWriter"/> object that receives the control content.</param>
 88        public override void RenderControl(HtmlTextWriter writer)
 89        {
 90            if (Post.Posts.Count <= 0)
 91            {
 92                return;
 93            }
 94            
 95            var html = RenderComments();
 96            writer.Write(html);
 97            writer.Write(Environment.NewLine);
 98        }
 99
100        #endregion
101
102        #region Methods
103
104        /// <summary>
105        /// Binds the comments.
106        /// </summary>
107        private static void BindComments()
108        {
109                var comments = (from post in Post.Posts
110                                where post.IsVisible
111                                from comment in post.Comments
112                                where comment.IsApproved
113                                select comment).ToList();
114
115                comments.Sort();
116                comments.Reverse();
117
118                RecentComments.Comments.Clear();
119                foreach (var comment in
120                    comments.Where(comment => comment.Email != "pingback" && comment.Email != "trackback").Take(BlogSettings.Instance.NumberOfRecentComments))
121                {
122                    Comments.Add(comment);
123                }
124        }
125
126        /// <summary>
127        /// Handles the Saved event of the Post control.
128        /// </summary>
129        /// <param name="sender">The source of the event.</param>
130        /// <param name="e">The <see cref="BlogEngine.Core.SavedEventArgs"/> instance containing the event data.</param>
131        private static void PostSaved(object sender, SavedEventArgs e)
132        {
133            if (e.Action == SaveAction.Update)
134            {
135                return;
136            }
137
138            BindComments();
139        }
140
141        /// <summary>
142        /// Renders the comments.
143        /// </summary>
144        /// <returns>The HTML string.</returns>
145        private static string RenderComments()
146        {
147            if (Comments.Count == 0)
148            {
149                return string.Format("<p>{0}</p>", labels.none);
150            }
151
152            using (var ul = new HtmlGenericControl("ul"))
153            {
154                ul.Attributes.Add("class", "recentComments");
155                ul.ID = "recentComments";
156
157                foreach (var comment in Comments.Where(comment => comment.IsApproved))
158                {
159                    var li = new HtmlGenericControl("li");
160
161                    // The post title
162                    var title = new HtmlAnchor { HRef = comment.Parent.RelativeLink, InnerText = comment.Parent.Title };
163                    title.Attributes.Add("class", "postTitle");
164                    li.Controls.Add(title);
165
166                    // The comment count on the post
167                    var count =
168                        new LiteralControl(string.Format(" ({0})<br />", ((Post)comment.Parent).ApprovedComments.Count));
169                    li.Controls.Add(count);
170
171                    // The author
172                    if (comment.Website != null)
173                    {
174                        var author = new HtmlAnchor { HRef = comment.Website.ToString(), InnerHtml = comment.Author };
175                        author.Attributes.Add("rel", "nofollow");
176                        li.Controls.Add(author);
177
178                        var wrote = new LiteralControl(string.Format(" {0}: ", labels.wrote));
179                        li.Controls.Add(wrote);
180                    }
181                    else
182                    {
183                        var author = new LiteralControl(string.Format("{0} {1}: ", comment.Author, labels.wrote));
184                        li.Controls.Add(author);
185                    }
186
187                    // The comment body
188                    var commentBody = Regex.Replace(comment.Content, @"\[(.*?)\]", string.Empty);
189                    var bodyLength = Math.Min(commentBody.Length, 50);
190
191                    commentBody = commentBody.Substring(0, bodyLength);
192                    if (commentBody.Length > 0)
193                    {
194                        if (commentBody[commentBody.Length - 1] == '&')
195                        {
196                            commentBody = commentBody.Substring(0, commentBody.Length - 1);
197                        }
198                    }
199
200                    commentBody += comment.Content.Length <= 50 ? " " : "? ";
201                    var body = new LiteralControl(commentBody);
202                    li.Controls.Add(body);
203
204                    // The comment link
205                    var link = new HtmlAnchor
206                        {
207                            HRef = string.Format("{0}#id_{1}", comment.Parent.RelativeLink, comment.Id), InnerHtml = string.Format("[{0}]", labels.more) 
208                        };
209                    link.Attributes.Add("class", "moreLink");
210                    li.Controls.Add(link);
211
212                    ul.Controls.Add(li);
213                }
214
215                using (var sw = new StringWriter())
216                {
217                    ul.RenderControl(new HtmlTextWriter(sw));
218                    return sw.ToString();
219                }
220            }
221        }
222
223        #endregion
224    }
225}