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