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

/BlogEngine/DotNetSlave.BusinessLogic/Web/Controls/PostViewBase.cs

#
C# | 356 lines | 222 code | 40 blank | 94 comment | 28 complexity | 056410e8938958c4d97b53b4f98cdc3b MD5 | raw file
  1namespace BlogEngine.Core.Web.Controls
  2{
  3    using System;
  4    using System.Globalization;
  5    using System.Text;
  6    using System.Text.RegularExpressions;
  7    using System.Web;
  8    using System.Web.UI;
  9    using System.Web.UI.WebControls;
 10
 11    /// <summary>
 12    /// The PostView.ascx that is located in the themes folder
 13    ///     has to inherit from this class.
 14    ///     <remarks>
 15    /// It provides the basic functionaly needed to display a post.
 16    ///     </remarks>
 17    /// </summary>
 18    public class PostViewBase : UserControl
 19    {
 20        #region Constants and Fields
 21
 22        /// <summary>
 23        /// Initializes a new instance of the <see cref="PostViewBase"/> class.
 24        /// </summary>
 25        public PostViewBase()
 26        {
 27            this.Location = ServingLocation.None;
 28            this.ContentBy = ServingContentBy.Unspecified;
 29        }
 30
 31        #endregion
 32
 33        #region Properties
 34
 35        /// <summary>
 36        ///     Gets the body of the post. Important: use this instead of Post.Content.
 37        /// </summary>
 38        public string Body
 39        {
 40            get
 41            {
 42                var post = this.Post;
 43                var body = post.Content;
 44
 45                if (this.ShowExcerpt)
 46                {
 47                    var link = string.Format(" <a href=\"{0}\">[{1}]</a>", post.RelativeLink, Utils.Translate("more"));
 48
 49                    if (!string.IsNullOrEmpty(post.Description))
 50                    {
 51                        body = post.Description.Replace(Environment.NewLine, "<br />") + link;
 52                    }
 53                    else
 54                    {
 55                        body = Utils.StripHtml(body);
 56                        if (body.Length > this.DescriptionCharacters && this.DescriptionCharacters > 0)
 57                        {
 58                            body = string.Format("{0}...{1}", body.Substring(0, this.DescriptionCharacters), link);
 59                        }
 60                    }
 61                }
 62
 63                var arg = new ServingEventArgs(body, this.Location, this.ContentBy);
 64                Post.OnServing(post, arg);
 65
 66                if (arg.Cancel)
 67                {
 68                    if (arg.Location == ServingLocation.SinglePost)
 69                    {
 70                        this.Response.Redirect("~/error404.aspx", true);
 71                    }
 72                    else
 73                    {
 74                        this.Visible = false;
 75                    }
 76                }
 77
 78                return arg.Body ?? string.Empty;
 79            }
 80        }
 81
 82        /// <summary>
 83        ///     Gets the comment feed link.
 84        /// </summary>
 85        /// <value>The comment feed.</value>
 86        public string CommentFeed
 87        {
 88            get
 89            {
 90                return this.Post.RelativeLink.Replace("/post/", "/post/feed/");
 91            }
 92        }
 93
 94        /// <summary>
 95        ///     Gets or sets the criteria by which the content is being served (by tag, category, author, etc).
 96        /// </summary>
 97        public ServingContentBy ContentBy { get; set; }
 98
 99        /// <summary>
100        ///     Gets or sets a value indicating how many characters should be shown of the description.
101        /// </summary>
102        public int DescriptionCharacters 
103        { 
104            get 
105            {
106                int chars = 0;
107                string url = HttpContext.Current.Request.RawUrl.ToUpperInvariant();
108
109                if (url.Contains("/CATEGORY/") || url.Contains("?TAG=/"))
110                {
111                    if (BlogSettings.Instance.ShowDescriptionInPostListForPostsByTagOrCategory)
112                    {
113                        return BlogSettings.Instance.DescriptionCharactersForPostsByTagOrCategory;
114                    }
115                }
116                else
117                {
118                    if (BlogSettings.Instance.ShowDescriptionInPostList)
119                    {
120                        return BlogSettings.Instance.DescriptionCharacters;
121                    }
122                }
123                return chars;
124            }
125        }
126
127        /// <summary>
128        ///     Gets or sets the index of the post in a list of posts displayed
129        /// </summary>
130        public int Index { get; set; }
131
132        /// <summary>
133        ///     Gets or sets the location where the serving takes place.
134        /// </summary>
135        public ServingLocation Location { get; set; }
136
137        /// <summary>
138        ///     Gets or sets the Post object that is displayed through the PostView.ascx control.
139        /// </summary>
140        /// <value>The Post object that has to be displayed.</value>
141        /// <remarks>
142        /// 
143        /// This was being stored to ViewState, though I can't see any reason why. Storing this
144        /// locally should improve performance.
145        /// 
146        /// </remarks>
147        public Post Post { get; set; }
148        //public virtual Post Post
149        //{
150        //    get
151        //    {
152        //        return (Post)this.ViewState["Post"];
153        //    }
154
155        //    set
156        //    {
157        //        this.ViewState["Post"] = value;
158        //    }
159        //}
160
161        /// <summary>
162        ///     Gets or sets a value indicating whether or not to show the entire post or just the excerpt/description.
163        /// </summary>
164        public bool ShowExcerpt { get; set; }
165
166        /// <summary>
167        ///     Gets an Edit and Delete link to any authenticated user.
168        /// </summary>
169        public virtual string AdminLinks
170        {
171            get
172            {
173                if (!Security.IsAuthenticated)
174                {
175                    return string.Empty;
176                }
177                else
178                {
179                    var postRelativeLink = this.Post.RelativeLink;
180
181                    var sb = new StringBuilder();
182
183                    if (Security.IsAuthorizedTo(Rights.ModerateComments))
184                    {
185                        if (this.Post.NotApprovedComments.Count > 0 &&
186                            BlogSettings.Instance.ModerationType != BlogSettings.Moderation.Disqus)
187                        {
188                            sb.AppendFormat(
189                                CultureInfo.InvariantCulture,
190                                "<a href=\"{0}\">{1} ({2})</a> | ",
191                                postRelativeLink,
192                                Utils.Translate("unapprovedcomments"),
193                                this.Post.NotApprovedComments.Count);
194                            sb.AppendFormat(
195                                CultureInfo.InvariantCulture,
196                                "<a href=\"{0}\">{1}</a> | ",
197                                postRelativeLink + "?approveallcomments=true",
198                                Utils.Translate("approveallcomments"));
199                        }
200                    }
201
202                    if (this.Post.CanUserEdit)
203                    {
204                        sb.AppendFormat(
205                            CultureInfo.InvariantCulture,
206                            "<a href=\"{0}\">{1}</a> | ",
207                        Utils.AbsoluteWebRoot + "admin/Posts/Add_entry.aspx?id=" + this.Post.Id,
208                            Utils.Translate("edit"));
209                    }
210
211                    if (this.Post.CanUserDelete)
212                    {
213                        var confirmDelete = string.Format(
214                              CultureInfo.InvariantCulture,
215                              Utils.Translate("areYouSure"),
216                              Utils.Translate("delete").ToLowerInvariant(),
217                              Utils.Translate("thePost"));
218                       
219                        sb.AppendFormat(
220                            CultureInfo.InvariantCulture,
221                            "<a href=\"#\" onclick=\"if (confirm('{2}')) location.href='{0}?deletepost={1}'\">{3}</a> | ",
222                            postRelativeLink,
223                            this.Post.Id,
224                            confirmDelete,
225                            Utils.Translate("delete"));
226                    }
227                    return sb.ToString();
228                }
229            }
230        }
231
232        /// <summary>
233        ///     Gets the rating.
234        /// Enable visitors to rate the post.
235        /// </summary>
236        public virtual string Rating
237        {
238            get
239            {
240                if (!BlogSettings.Instance.EnableRating || !Security.IsAuthorizedTo(AuthorizationCheck.HasAll, Rights.ViewRatingsOnPosts, Rights.SubmitRatingsOnPosts))
241                {
242                    return string.Empty;
243                }
244
245                const string Script = "<div class=\"ratingcontainer\" style=\"visibility:hidden\">{0}|{1}|{2}</div>";
246                return string.Format(
247                    Script,
248                    this.Post.Id,
249                    this.Post.Raters,
250                    this.Post.Rating.ToString("#.0", CultureInfo.InvariantCulture));
251            }
252        }
253
254        #endregion
255
256        #region Methods
257
258        /// <summary>
259        /// Displays the Post's categories seperated by the specified string.
260        /// </summary>
261        /// <param name="separator">
262        /// The separator.
263        /// </param>
264        /// <returns>
265        /// The category links.
266        /// </returns>
267        public virtual string CategoryLinks(string separator)
268        {
269            var keywords = new string[this.Post.Categories.Count];
270            const string Link = "<a href=\"{0}\">{1}</a>";
271            for (var i = 0; i < this.Post.Categories.Count; i++)
272            {
273                var c = Category.GetCategory(this.Post.Categories[i].Id);
274                if (c != null)
275                {
276                    keywords[i] = string.Format(CultureInfo.InvariantCulture, Link, c.RelativeLink, c.Title);
277                }
278            }
279
280            return string.Join(separator, keywords);
281        }
282
283        /// <summary>
284        /// Raises the <see cref="E:System.Web.UI.Control.Init"/> event.
285        /// </summary>
286        /// <param name="e">An <see cref="T:System.EventArgs"/> object that contains the event data.</param>
287        protected override void OnInit(EventArgs e)
288        {
289            base.OnInit(e);
290
291            if (!this.Post.IsVisible)
292            {
293                this.Visible = false;
294            }
295        }
296
297        /// <summary>
298        /// Raises the <see cref="E:System.Web.UI.Control.Load"/> event.
299        /// </summary>
300        /// <param name="e">The <see cref="T:System.EventArgs"/> object that contains the event data.</param>
301        /// <remarks>
302        /// Lets process our .Body content and build up our controls collection
303        /// inside the 'BodyContent' placeholder.
304        /// User controls are insterted into the blog in the following format..
305        /// [UserControl:~/path/usercontrol.ascx]
306        /// TODO : Expose user control parameters.
307        /// </remarks>
308        protected override void OnLoad(EventArgs e)
309        {
310            base.OnLoad(e);
311
312
313            var bodyContent = (PlaceHolder)this.FindControl("BodyContent");
314            if (bodyContent == null)
315            {
316                // We have no placeholder so we assume this is an old style <% =Body %> theme and do nothing.
317            }
318            else
319            {
320                Utils.InjectUserControls(bodyContent, this.Body);
321            }
322        }
323
324        /// <summary>
325        /// Displays the Post's tags seperated by the specified string.
326        /// </summary>
327        /// <param name="separator">
328        /// The separator.
329        /// </param>
330        /// <returns>
331        /// The tag links.
332        /// </returns>
333        public virtual string TagLinks(string separator)
334        {
335            var tags = this.Post.Tags;
336            if (tags.Count == 0)
337            {
338                return null;
339            }
340
341            var tagStrings = new string[tags.Count];
342            const string Link = "<a href=\"{0}/{1}\" rel=\"tag\">{2}</a>";
343            var path = Utils.RelativeWebRoot + "?tag=";
344            for (var i = 0; i < tags.Count; i++)
345            {
346                var tag = tags[i];
347                tagStrings[i] = string.Format(
348                    CultureInfo.InvariantCulture, Link, path, HttpUtility.UrlEncode(tag), HttpUtility.HtmlEncode(tag));
349            }
350
351            return string.Join(separator, tagStrings);
352        }
353
354        #endregion
355    }
356}