PageRenderTime 52ms CodeModel.GetById 43ms app.highlight 7ms RepoModel.GetById 1ms app.codeStats 0ms

/BlogEngine/BlogEngine.NET/App_Code/Controls/SearchOnSearch.cs

#
C# | 181 lines | 90 code | 29 blank | 62 comment | 10 complexity | 82c87b22d63db72b28efdc93e94d7aa9 MD5 | raw file
  1// --------------------------------------------------------------------------------------------------------------------
  2// <summary>
  3//   If the visitor arrives through a search engine, this control
  4//   will display an in-site search result based on the same search term.
  5// </summary>
  6// --------------------------------------------------------------------------------------------------------------------
  7
  8namespace App_Code.Controls
  9{
 10    using System.Collections.Generic;
 11    using System.Text;
 12    using System.Text.RegularExpressions;
 13    using System.Web;
 14    using System.Web.UI;
 15
 16    using BlogEngine.Core;
 17
 18    /// <summary>
 19    /// If the visitor arrives through a search engine, this control
 20    ///     will display an in-site search result based on the same search term.
 21    /// </summary>
 22    public class SearchOnSearch : Control
 23    {
 24        #region Constants and Fields
 25
 26        /// <summary>
 27        /// The rx search term.
 28        /// </summary>
 29        private static readonly Regex RxSearchTerm;
 30
 31        #endregion
 32
 33        #region Constructors and Destructors
 34
 35        /// <summary>
 36        /// Initializes static members of the <see cref="SearchOnSearch"/> class.
 37        /// </summary>
 38        static SearchOnSearch()
 39        {
 40            // Matches the query string parameter "q" and its value.  Does not match if "q" is blank.
 41            RxSearchTerm = new Regex(
 42                "[?&]q=([^&#]+)", RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);
 43        }
 44
 45        #endregion
 46
 47        #region Properties
 48
 49        /// <summary>
 50        ///     Gets or sets the text of the headline.
 51        /// </summary>
 52        public string Headline { get; set; }
 53
 54        /// <summary>
 55        ///     Gets or sets the maximum numbers of results to display.
 56        /// </summary>
 57        public int MaxResults { get; set; }
 58
 59        /// <summary>
 60        ///     Gets or sets the text displayed below the headline.
 61        /// </summary>
 62        public string Text { get; set; }
 63
 64        /// <summary>
 65        ///     Gets a value indicating whether the referrer is from a search engine.
 66        /// </summary>
 67        private bool IsSearch
 68        {
 69            get
 70            {
 71                if (this.Context.Request.UrlReferrer != null)
 72                {
 73                    var referrer = this.Context.Request.UrlReferrer.ToString().ToLowerInvariant();
 74                    return RxSearchTerm.IsMatch(referrer);
 75                }
 76
 77                return false;
 78            }
 79        }
 80
 81        #endregion
 82
 83        #region Public Methods
 84
 85        /// <summary>
 86        /// Renders the control as a script tag.
 87        /// </summary>
 88        /// <param name="writer">
 89        /// The writer.
 90        /// </param>
 91        public override void RenderControl(HtmlTextWriter writer)
 92        {
 93            var html = this.Html();
 94            if (html != null)
 95            {
 96                writer.Write(html);
 97            }
 98        }
 99
100        #endregion
101
102        #region Methods
103
104        /// <summary>
105        /// Retrieves the search term from the specified referrer string.
106        /// </summary>
107        /// <param name="referrer">
108        /// The referrer.
109        /// </param>
110        /// <returns>
111        /// The get search term.
112        /// </returns>
113        private static string GetSearchTerm(string referrer)
114        {
115            var term = string.Empty;
116            var match = RxSearchTerm.Match(referrer);
117
118            if (match.Success)
119            {
120                term = match.Groups[1].Value;
121            }
122
123            return term.Replace("+", " ");
124        }
125
126        /// <summary>
127        /// Checks the referrer to see if it qualifies as a search.
128        /// </summary>
129        /// <returns>
130        /// The html string.
131        /// </returns>
132        private string Html()
133        {
134            if (this.Context.Request.UrlReferrer != null &&
135                !this.Context.Request.UrlReferrer.ToString().Contains(Utils.AbsoluteWebRoot.ToString()) && this.IsSearch)
136            {
137                var referrer = this.Context.Request.UrlReferrer.ToString().ToLowerInvariant();
138                var searchTerm = GetSearchTerm(referrer);
139                var items = Search.Hits(searchTerm, false);
140                return items.Count == 0 ? null : this.WriteHtml(items, searchTerm);
141            }
142
143            return null;
144        }
145
146        /// <summary>
147        /// Writes the search results as HTML.
148        /// </summary>
149        /// <param name="items">
150        /// The items.
151        /// </param>
152        /// <param name="searchTerm">
153        /// The search Term.
154        /// </param>
155        /// <returns>
156        /// The write html.
157        /// </returns>
158        private string WriteHtml(IList<IPublishable> items, string searchTerm)
159        {
160            var results = this.MaxResults < items.Count ? this.MaxResults : items.Count;
161            var sb = new StringBuilder();
162            sb.Append("<div id=\"searchonsearch\">");
163            sb.AppendFormat(
164                "<h3>{0} '{1}'</h3>", this.Headline, HttpUtility.HtmlEncode(HttpUtility.UrlDecode(searchTerm)));
165            sb.AppendFormat("<p>{0}</p>", this.Text);
166            sb.Append("<ol>");
167
168            for (var i = 0; i < results; i++)
169            {
170                sb.AppendFormat("<li><a href=\"{0}\">{1}</a></li>", items[i].RelativeLink, items[i].Title);
171            }
172
173            sb.Append("</ol>");
174            sb.Append("</div>");
175
176            return sb.ToString();
177        }
178
179        #endregion
180    }
181}