using System; using System.Collections.Generic; using System.Data; using System.Collections; using System.Text.RegularExpressions; using System.Web; using System.Web.UI; using CMS.CMSHelper; using CMS.EventLog; using CMS.GlobalHelper; using CMS.IO; using CMS.PortalControls; using CMS.SiteProvider; using NetSpell.SpellChecker; using NetSpell.SpellChecker.Dictionary; public partial class CMSWebParts_Search_DidYouMean : CMSAbstractWebPart { private const string startTag = "##START_SUGG##"; private const string endTag = "##END_SUGG##"; private const string searchUrlParameter = "searchtext"; #region "Properties" /// /// Gets or sets value of language. /// public string Language { get { return ValidationHelper.GetString(GetValue("Language"), ""); } set { SetValue("Language", value); } } /// /// Gets or sets value of text message. /// public string Text { get { return ValidationHelper.GetString(GetValue("Text"), ""); } set { SetValue("Text", value); } } /// /// Gets or sets value of starting tag. /// public string StartTag { get { return ValidationHelper.GetString(GetValue("StartTag"), ""); } set { SetValue("StartTag", value); } } /// /// Gets or sets value of ending tag. /// public string EndTag { get { return ValidationHelper.GetString(GetValue("EndTag"), ""); } set { SetValue("EndTag", value); } } #endregion #region "Methods" /// /// Content loaded event handler. /// public override void OnContentLoaded() { base.OnContentLoaded(); SetupControl(); } /// /// Initializes the control properties. /// protected void SetupControl() { if (StopProcessing) { // Do nothing } else { // Get search terms string searchtext = QueryHelper.GetString(searchUrlParameter, String.Empty); // Use try/catch block. Search text can be un-parsered for query parser try { // Get search clauses -> searched words SearchQueryClauses clauses = SearchQueryHelper.GetQueryClauses(searchtext, "_content"); if (clauses != null) { // Get collection of highlights clauses.GetQuery(false, true); List searchTerms = clauses.HighlightedWords; string currentCulture = String.IsNullOrEmpty(Language.Trim()) ? CMSContext.PreferredCultureCode : Language; // Get suggestions string dicFileName = currentCulture + ".dic"; string suggestion = DidYouMean(dicFileName, searchtext, searchTerms); // Show only if there is something to suggest if (suggestion != String.Empty) { string queryText = HTMLHelper.HTMLEncode(suggestion).Replace(startTag, String.Empty).Replace(endTag, String.Empty); string visibleText = HTMLHelper.HTMLEncode(suggestion).Replace(startTag, StartTag).Replace(endTag, EndTag); // Change value of search parameter string url = URLHelper.RemoveParameterFromUrl(URLHelper.CurrentURL, searchUrlParameter); url = URLHelper.AddParameterToUrl(url, searchUrlParameter, queryText); ltrText.Text = Text; lnkSearch.NavigateUrl = url; lnkSearch.Text = visibleText; } else { Visible = false; } } else { Visible = false; } } catch { Visible = false; } } } /// /// Did you mean suggestion. /// private static string DidYouMean(string dictionaryFile, string searchQuery, IEnumerable searchTerms) { if (searchTerms != null) { Spelling SpellChecker = null; WordDictionary WordDictionary = null; #region "Word dictionary" // If not in cache, create new WordDictionary = new WordDictionary(); WordDictionary.EnableUserFile = false; // Getting folder for dictionaries string folderName = HttpContext.Current.Request.MapPath("~/App_Data/Dictionaries/"); // Check if dictionary file exists string fileName = Path.Combine(folderName, dictionaryFile); if (!File.Exists(fileName)) { EventLogProvider eventLog = new EventLogProvider(); eventLog.LogEvent(EventLogProvider.EVENT_TYPE_ERROR, DateTime.Now, "DidYouMean webpart", "Dictionary file not found!"); return String.Empty; } WordDictionary.DictionaryFolder = folderName; WordDictionary.DictionaryFile = dictionaryFile; // Load and initialize the dictionary WordDictionary.Initialize(); #endregion #region "SpellCheck" // Prepare spellchecker SpellChecker = new Spelling(); SpellChecker.Dictionary = WordDictionary; SpellChecker.SuggestionMode = Spelling.SuggestionEnum.NearMiss; bool suggest = false; // Check all searched terms foreach (string term in searchTerms) { if (term.Length > 2) { SpellChecker.Suggest(term); ArrayList al = SpellChecker.Suggestions; // If there are some suggestions if ((al != null) && (al.Count > 0)) { suggest = true; // Expression to find term Regex regex = RegexHelper.GetRegex("([\\+\\-\\s\\(]|^)" + term + "([\\s\\)]|$)"); // Change term in original search query string suggestion = "$1" + startTag + al[0] + endTag + "$2"; searchQuery = regex.Replace(searchQuery, suggestion); } } } #endregion if (suggest) { return searchQuery; } } return String.Empty; } /// /// Reloads the control data. /// public override void ReloadData() { base.ReloadData(); SetupControl(); } #endregion }