/Release/SSC-KP-20130517/Intranet.root/Intranet.Website/Plugins/GSA/GSA.ascx.cs
C# | 1604 lines | 1387 code | 98 blank | 119 comment | 122 complexity | 90bf1439e1715cb88619ae4838224b99 MD5 | raw file
Possible License(s): LGPL-2.0, GPL-2.0, LGPL-2.1
- using System;
- using System.Collections;
- using System.Configuration;
- using System.Data;
- using System.Linq;
- using System.Web;
- using System.Web.Security;
- using System.Web.UI;
- using System.Web.UI.HtmlControls;
- using System.Web.UI.WebControls;
- using System.Web.UI.WebControls.WebParts;
- using System.Xml;
-
- using Intranet.Utils;
- using Intranet.WebSite.Domain;
- using Intranet.WebSite.ConfigurationSections;
- using Intranet.ComponentLibrary;
- using Intranet.ComponentLibrary.ComponentLibraryComponents;
- using Intranet.WebSite.Plugins.Search;
- using Intranet.XmlObjects;
- using Intranet.XmlObjects.LanguagePacks;
- using System.Collections.Generic;
- using System.Text;
- using System.Text.RegularExpressions;
- using Intranet.Domain.ConfigurationSections;
- using System.Net;
- using System.Diagnostics;
-
- namespace Intranet.WebSite.Plugins.GSA
- {
- public partial class GSA : BaseWebSitePlugin
- {
- private const string GOOGLE_RESULTS_XSLT_NL = @"~/App_Data/DataFormatting/GoogleResultsNL.xslt";
- private const string GOOGLE_RESULTS_XSLT_EN = @"~/App_Data/DataFormatting/GoogleResultsENStandard.xslt";
-
- private const string PLUGINNAME = "SearchResults";
- private const string PLUGINCONFIGNAME = "SearchResultsConfig";
-
- protected GSALanguagePack currentLanguagePack;
-
- private List<Facet> facets = new List<Facet>();
-
- private List<Facet> facetsGeneral = new List<Facet>();
- private List<Facet> facetsIntranet = new List<Facet>();
- private List<Facet> facetsKennisplein = new List<Facet>();
-
-
- #region Init & Load
-
- protected override void OnInit(EventArgs e)
- {
- this.Name = PLUGINNAME;
-
- if (string.IsNullOrEmpty(this.ConfigurationName))
- {
- this.ConfigurationName = PLUGINCONFIGNAME;
- }
-
- base.OnInit(e);
-
- this.LoadLanguagePack();
- }
-
- private void LoadLanguagePack()
- {
- string languageFile = string.Empty;
- foreach (languagepack lp in this.CurrentConfiguration.languagepacks)
- {
- if (lp.cultureInfo == System.Globalization.CultureInfo.CurrentCulture.Name)
- {
- languageFile = lp.location;
- break;
- }
- }
- this.currentLanguagePack = new GSALanguagePack();
- this.currentLanguagePack = ObjectXMLSerializer<GSALanguagePack>.Load(Server.MapPath(languageFile));
- }
-
- protected void Page_Load(object sender, EventArgs e)
- {
- var searchParameters = GetSearchParameters(this.Request);
-
- InitializeAdvancedSearchControls(searchParameters);
-
- if (ContainsGSAQuery(searchParameters))
- {
- // Set search textbox to be the same as first advanced textbox.
- SearchTerm.Value = SearchTermAll.Value;
-
- string resultString = BuildResultString(searchParameters);
- SearchedFor.Text = HttpUtility.HtmlEncode(resultString);
- this.Page.Title = resultString;
- }
- else
- {
- if (searchParameters.ContainsKey("AdvancedSearch") && searchParameters["AdvancedSearch"] == "on")
- {
- this.Page.Title = currentLanguagePack.TitleAdvanced;
- }
- else
- {
- this.Page.Title = currentLanguagePack.TitleNormal;
- }
- }
-
- if (searchParameters.ContainsKey("AdvancedSearch") && searchParameters["AdvancedSearch"] == "on")
- {
- //this.SearchPageTitleLiteral.Text = "<h1>Geadvanceerde Zoeken</h1>";
- //this.AdvancedSearchLinkLiteral.Text = "<a href=\"javascript:void(0)\" class=\"AdvancedSearchLink\">Geadvanceerd zoeken Aan</a> <a href=\"javascript:void(0)\" class=\"AdvancedSearchLink\">Wissen</a>";
- this.SearchPageTitleLiteral.Text = String.Format("<h1>{0}</h1>", currentLanguagePack.TitleAdvanced);
- this.AdvancedSearchLinkLiteral.Text = String.Format("<a id=\"AdvancedSearchToggle\" href=\"javascript:void(0)\" class=\"AdvancedSearchLink\">{0}</a> <a id=\"AdvancedSearchClear\" href=\"javascript:void(0)\" class=\"AdvancedSearchLink\">{1}</a>", currentLanguagePack.AdvancedButtonOpen, currentLanguagePack.AdvancedButtonErase);
- }
- else
- {
- //this.SearchPageTitleLiteral.Text = "<h1>Zoeken</h1>";
- //this.AdvancedSearchLinkLiteral.Text = "<a href=\"javascript:void(0)\" class=\"AdvancedSearchLink\">Geadvanceerd zoeken</a>";
- this.SearchPageTitleLiteral.Text = String.Format("<h1>{0}</h1>", currentLanguagePack.TitleNormal);
- this.AdvancedSearchLinkLiteral.Text = String.Format("<a id=\"AdvancedSearchToggle\" href=\"javascript:void(0)\" class=\"AdvancedSearchLink\">{0}</a>", currentLanguagePack.AdvancedButtonClosed);
- }
-
- // Get results
- if (ContainsGSAQuery(searchParameters))
- {
- // Make sure we have xml output, and add any missing parameters.
- searchParameters["output"] = "xml_no_dtd";
- if (!searchParameters.ContainsKey("client")) searchParameters["client"] = this.currentLanguagePack.Client_FrontEnd;
- if (!searchParameters.ContainsKey("site")) searchParameters["site"] = this.currentLanguagePack.DefaultCollection;
- if (!searchParameters.ContainsKey("ie")) searchParameters["ie"] = "utf8";
- if (!searchParameters.ContainsKey("oe")) searchParameters["oe"] = "utf8";
- if (!searchParameters.ContainsKey("filter")) searchParameters["filter"] = "p"; // Else GSA sees all results from Kennisplein as the same
- if (searchParameters.ContainsKey("as_q")) searchParameters["dnavs"] = searchParameters["as_q"];
-
- // Turn advanced panel off
- if (searchParameters.ContainsKey("ShowAdvancedPanel")) searchParameters.Remove("ShowAdvancedPanel");
-
- var keys = new List<string>(searchParameters.Keys);
- foreach (var key in keys)
- {
- searchParameters[key] = DecodeUnicodeChars(searchParameters[key], true);
- }
-
- // Strip periods (.) from partialfields. Fixes searching for initials in author field, e.g. 'A.B. Fielding' becomes 'AB Fielding'.
- if (searchParameters.ContainsKey("partialfields"))
- {
- searchParameters["partialfields"] = searchParameters["partialfields"].Replace("%2E", String.Empty);
- }
-
- if (!searchParameters.ContainsKey("as_q"))
- {
- searchParameters.Add("as_q", "site:nl");
- }
-
- if (searchParameters.ContainsKey("as_q") && searchParameters["as_q"] == string.Empty)
- {
- searchParameters["as_q"] = "site:nl";
- }
-
- if (!searchParameters.ContainsKey("rc"))
- {
- //Always get actual result count instead of estimated
- searchParameters.Add("rc", "1");
- }
-
- this.GetResults(this.currentLanguagePack.GSAUrl + "?" + DictionaryToQuerystring(searchParameters));
- }
-
- //Set GSA Alerts Script
- int positionSearch = this.currentLanguagePack.GSAUrl.IndexOf("search");
- string serverAdres = this.currentLanguagePack.GSAUrl.Remove(positionSearch, 6);
- AlertJSLiteral.Text = "<script >function getHomeUrl() {return location.href = \"" + serverAdres + "ealerts?shu=\" + escape(document.location.href);}</script>";
-
- this.MyAlertsTitleLiteral.Text = this.currentLanguagePack.GSAAlertsText;
- this.GSAHelpLiteral.Text = "<img src=\"/App_Themes/1Logo/images/infoicon_small.jpg\" class=\"GSAInfo\" title='<div class=\"GSAAlertsInfo\">" +
- this.currentLanguagePack.GSAAlertsInfo +
- "</div>' />";
- }
-
- private static bool ContainsGSAQuery(Dictionary<string, string> searchParameters)
- {
- return searchParameters != null
- && !(searchParameters.Count == 2 && searchParameters.ContainsKey("AdvancedSearch") && searchParameters.ContainsKey("ShowAdvancedPanel"))
- && !(searchParameters.Count == 1 && searchParameters.ContainsKey("AdvancedSearch"))
- && !(searchParameters.Count == 0);
- }
-
- private static Dictionary<string, string> GetSearchParameters(HttpRequest currentRequest)
- {
- //var searchParameters = new Dictionary<string, string>();
-
- var searchParameters = QuerystringToDictionary(currentRequest);
- if (searchParameters == null) searchParameters = new Dictionary<string, string>();
-
- // Three possibilities: either 'SearchTerm' or Google-like params ('q', etc) in querystring, or a form post.
- if (!String.IsNullOrEmpty(currentRequest.QueryString["SearchTerm"]))
- {
- //searchParameters["q"] = HttpUtility.UrlEncode(currentRequest.QueryString["SearchTerm"]);
- searchParameters["q"] = currentRequest.QueryString["SearchTerm"];
- searchParameters.Remove("SearchTerm");
- }
- //else if (!string.IsNullOrEmpty(currentRequest.QueryString.ToString()))
- //{
- //var querystring = currentRequest.QueryString.ToString();
-
- // For some reason '+' is used instead of '%20'. Manually decoding them here as they don't get decoded like the rest.
- //querystring = querystring.Replace('+', ' ');
-
- //searchParameters = QuerystringToDictionary(querystring);
- // searchParameters = QuerystringToDictionary(currentRequest);
- //}
- else if (!string.IsNullOrEmpty(currentRequest.Form["SearchTerm"]))
- {
- //searchParameters["q"] = HttpUtility.UrlEncode(currentRequest.Form["SearchTerm"].ToString());
- searchParameters["q"] = currentRequest.Form["SearchTerm"].ToString();
- }
-
- var keys = new List<string>(searchParameters.Keys);
- foreach (var key in keys)
- {
- searchParameters[key] = DecodeUnicodeChars(searchParameters[key], true);
- }
-
- return searchParameters;
- }
-
- //private string BuildSearchTerm(Dictionary<string, string> searchParameters)
- //{
- // var terms = new List<string>();
-
- // // 'All words'
- // if (searchParameters.ContainsKey("q") && !String.IsNullOrEmpty(searchParameters["q"])) terms.Add(searchParameters["q"]);
-
- // // 'Any words'
- // if (searchParameters.ContainsKey("as_oq") && !String.IsNullOrEmpty(searchParameters["as_oq"]))
- // {
- // terms.Add(String.Join(" OR ", searchParameters["as_oq"].Split(' ')));
- // }
-
- // // 'Exact phrase'
- // if (searchParameters.ContainsKey("as_epq") && !String.IsNullOrEmpty(searchParameters["as_epq"]))
- // {
- // terms.Add("\"" + searchParameters["as_epq"] + "\"");
- // }
-
- // // 'Without words'
- // if (searchParameters.ContainsKey("as_eq") && !String.IsNullOrEmpty(searchParameters["as_eq"]))
- // {
- // var without = searchParameters["as_eq"].Split(' ');
- // terms.Add(String.Join(" ", without.Select(term => "-" + term).ToArray()));
- // }
-
- // //for (var i = 0; i < terms.Count; i++)
- // //{
- // // terms[i] = HttpUtility.UrlDecode(terms[i]);
- // //}
-
- // return String.Join(" ", terms.ToArray());
- //}
-
- private void InitializeAdvancedSearchControls(Dictionary<string, string> searchParameters)
- {
- // Initialize 'Source' dropdown list
- if (FilterBySource.Items.Count == 0)
- {
- //FilterBySource.Items.Add(new ListItem("Alle resultaten", "default_collection"));
- //var defaultSource = new ListItem("Alle resultaten", String.Empty);
- var defaultSource = new ListItem(currentLanguagePack.FilterBySourceDefaultValue, String.Empty);
- FilterBySource.Items.Add(defaultSource);
- defaultSource.Selected = true;
-
- // Collections string format example: 'IenM:staging-1ntra|Kennisplein:Kennisplein'
- //var collections = new Dictionary<string, string>();
- if (!String.IsNullOrEmpty(this.currentLanguagePack.Collections))
- {
- var pairs = this.currentLanguagePack.Collections.Split('|');
- foreach (var pair in pairs)
- {
- var col = pair.Split(':');
- FilterBySource.Items.Add(new ListItem(col[0], col[1]));
- }
- }
-
- if (FilterBySource.Items.Count <= 2)
- {
- //Only have 1 collection no need to show the filter by collection
- FilterBySourcePanel.Visible = false;
- }
-
- }
-
- //if (FilterByLanguage.Items.Count == 0)
- //{
- // foreach (var kvp in languageCodesToPrettyName)
- // {
- // FilterByLanguage.Items.Add(new ListItem(kvp.Value, kvp.Key));
- // }
- //}
-
- if (FilterByFiletype.Items.Count == 0)
- {
- foreach (var kvp in filetypes)
- {
- FilterByFiletype.Items.Add(new ListItem(kvp.Key, kvp.Value));
- }
- }
-
- FillAdvancedSearchInputs(searchParameters);
- }
-
- private void FillAdvancedSearchInputs(Dictionary<string, string> searchParameters)
- {
- // 'All words'
- if (searchParameters.ContainsKey("q") && !String.IsNullOrEmpty(searchParameters["q"]))
- {
- SearchTermAll.Value = searchParameters["q"];
- }
-
- // 'Any words'
- if (searchParameters.ContainsKey("as_oq") && !String.IsNullOrEmpty(searchParameters["as_oq"]))
- {
- var orTerms = searchParameters["as_oq"].Split(' ');
- for (int i = 0; i < orTerms.Length; i++)
- {
- if (i == 0) SearchTermAny1.Value = orTerms[i];
- if (i == 1) SearchTermAny2.Value = orTerms[i];
- if (i == 2) SearchTermAny3.Value = orTerms[i];
- }
- }
-
- // 'Exact phrase'
- if (searchParameters.ContainsKey("as_epq") && !String.IsNullOrEmpty(searchParameters["as_epq"]))
- {
- SearchTermPhrase.Value = searchParameters["as_epq"];
- }
-
- // 'Without words'
- if (searchParameters.ContainsKey("as_eq") && !String.IsNullOrEmpty(searchParameters["as_eq"]))
- {
- SearchTermWithout.Value = searchParameters["as_eq"];
- }
-
- // Source
- if (searchParameters.ContainsKey("site") && !String.IsNullOrEmpty(searchParameters["site"]))
- {
- foreach (ListItem sourceItem in FilterBySource.Items)
- {
- if (String.Equals(searchParameters["site"], sourceItem.Value, StringComparison.OrdinalIgnoreCase))
- {
- sourceItem.Selected = true;
- break;
- }
- }
- }
-
- if (searchParameters.ContainsKey("partialfields") && !String.IsNullOrEmpty(searchParameters["partialfields"]))
- {
- var partialFields = searchParameters["partialfields"];
-
- // Author
- List<string> authorParts = new List<string>();
- var authorRegex = new Regex(@"author:([^\.\|\)]+)", RegexOptions.IgnoreCase);
- foreach (Match m in authorRegex.Matches(searchParameters["partialfields"]))
- {
- if (m != null && m.Groups != null && m.Groups.Count >= 2) authorParts.Add(m.Groups[1].Value);
- }
- var author = String.Join(" ", authorParts.ToArray());
- author = author.Replace("%2E", ".");
- if (!String.IsNullOrEmpty(author)) FilterByAuthor.Value = author;
-
- // Language
- //var languagePattern = new Regex(@"dc%3Alanguage:([a-z]+)", RegexOptions.IgnoreCase);
- //var selectedLanguages = new List<string>();
- //foreach (Match m in languagePattern.Matches(partialFields))
- //{
- // if (m != null && m.Groups != null && m.Groups.Count >= 2) selectedLanguages.Add(m.Groups[1].Value);
- //}
- //foreach (ListItem languageItem in FilterByLanguage.Items)
- //{
- // languageItem.Selected = selectedLanguages.Contains(languageItem.Value);
- //}
- }
-
- if (searchParameters.ContainsKey("as_q") && !String.IsNullOrEmpty(searchParameters["as_q"]))
- {
- var as_qParameters = SplitAs_qParametersString(searchParameters["as_q"]);
-
- // Filetype
- foreach (ListItem filetypeItem in FilterByFiletype.Items)
- {
- if (!String.IsNullOrEmpty(filetypeItem.Value))
- {
- //filetypeItem.Selected = as_qParameters.Any(p => p.Contains("filetype:" + filetypeItem.Value.Split(',')[0], StringComparison.OrdinalIgnoreCase));
- filetypeItem.Selected = as_qParameters.Any(p => p.Contains("ext:" + filetypeItem.Value.Split(';')[0], StringComparison.OrdinalIgnoreCase));
- }
- }
-
- // Dates
- //var dateParam = as_qParameters.Find(p => p.Contains("daterange:", StringComparison.OrdinalIgnoreCase));
- var dateParam = as_qParameters.Find(p => p.Contains("inmeta:dc%3Adate:", StringComparison.OrdinalIgnoreCase));
- if (!String.IsNullOrEmpty(dateParam))
- {
- //var datesRegex = new Regex(@"daterange:(\d{4}-\d{1,2}-\d{1,2})?\.\.(\d{4}-\d{1,2}-\d{1,2})?", RegexOptions.IgnoreCase);
- var datesRegex = new Regex(@"inmeta:dc%3Adate:(\d{4}-\d{1,2}-\d{1,2})?\.\.(\d{4}-\d{1,2}-\d{1,2})?", RegexOptions.IgnoreCase);
-
- var match = datesRegex.Match(dateParam);
- if (match != null && match.Groups != null && match.Groups.Count >= 2)
- {
- SearchDateFrom.Value = ReverseDateString(match.Groups[1].Value);
- SearchDateTo.Value = ReverseDateString(match.Groups[2].Value);
- }
- }
- }
- }
-
- private string BuildResultString(Dictionary<string, string> searchParameters)
- {
- var descriptions = new List<string>();
-
- // 'All words'
- if (searchParameters.ContainsKey("q") && !String.IsNullOrEmpty(searchParameters["q"]))
- descriptions.Add(String.Format(currentLanguagePack.ResultDescriptionAllWords, searchParameters["q"]));
-
- // 'Any words'
- if (searchParameters.ContainsKey("as_oq") && !String.IsNullOrEmpty(searchParameters["as_oq"]))
- {
- string textValue = string.Empty;
- string[] splitValues = searchParameters["as_oq"].Split();
- for (int i = 0; i < splitValues.Length; i++)
- {
- textValue += "'" + splitValues[i] + "'";
- if (i < splitValues.Length - 1)
- {
- textValue += " " + currentLanguagePack.AdvancedControlOR + " ";
- }
- }
-
- descriptions.Add(String.Format(currentLanguagePack.ResultDescriptionAnyWords, textValue));
- }
-
- // 'Exact phrase'
- if (searchParameters.ContainsKey("as_epq") && !String.IsNullOrEmpty(searchParameters["as_epq"]))
- descriptions.Add(String.Format(currentLanguagePack.ResultDescriptionExactPhrase, searchParameters["as_epq"]));
-
- // 'Without words'
- if (searchParameters.ContainsKey("as_eq") && !String.IsNullOrEmpty(searchParameters["as_eq"]))
- descriptions.Add(String.Format(currentLanguagePack.ResultDescriptionWithoutWords, searchParameters["as_eq"]));
-
- // Source
- if (searchParameters.ContainsKey("site") && !String.IsNullOrEmpty(searchParameters["site"]))
- {
- var siteListItem = FilterBySource.Items.FindByValue(searchParameters["site"]);
- if (siteListItem != null && siteListItem != FilterBySource.Items[0])
- descriptions.Add(String.Format(currentLanguagePack.ResultDescriptionSourceFilter, siteListItem.Text));
- }
-
- if (searchParameters.ContainsKey("partialfields") && !String.IsNullOrEmpty(searchParameters["partialfields"]))
- {
- // Author
- List<string> authorParts = new List<string>();
- var authorRegex = new Regex(@"author:([^\.\|\)]+)", RegexOptions.IgnoreCase);
- foreach (Match m in authorRegex.Matches(searchParameters["partialfields"]))
- {
- if (m != null && m.Groups != null && m.Groups.Count >= 2) authorParts.Add(m.Groups[1].Value);
- }
- var author = String.Join(" ", authorParts.ToArray());
- author = author.Replace("%2E", ".");
- if (!String.IsNullOrEmpty(author)) descriptions.Add(String.Format(currentLanguagePack.ResultDescriptionByAuthor, author));
-
- // Language
- //var selectedLanguages = new List<string>();
-
- //var languageRegex = new Regex(@"dc%3Alanguage:([a-z]+)", RegexOptions.IgnoreCase);
- //foreach (Match matchLang in languageRegex.Matches(searchParameters["partialfields"]))
- //{
- // if (matchLang != null && matchLang.Groups != null && matchLang.Groups.Count >= 2)
- // {
- // var language = matchLang.Groups[1].Value;
- // if (!String.IsNullOrEmpty(language)) selectedLanguages.Add(LanguageCodesToPrettyText(language));
- // }
- //}
-
- //if (selectedLanguages.Count > 0)
- //{
- // var langText = String.Join(" of ", selectedLanguages.ToArray());
- // descriptions.Add(String.Format(currentLanguagePack.ResultDescriptionLanguage, langText));
- //}
- }
-
- // Filetype / extensions
- if (searchParameters.ContainsKey("as_q") && !String.IsNullOrEmpty(searchParameters["as_q"]))
- {
- var selectedFiletypes = new List<string>();
-
- var extensionRegex = new Regex(@"ext:([a-z]+)", RegexOptions.IgnoreCase);
-
- foreach (Match matchExt in extensionRegex.Matches(searchParameters["as_q"]))
- {
- if (matchExt != null && matchExt.Groups != null && matchExt.Groups.Count >= 2)
- {
- var ext = matchExt.Groups[1].Value;
- if (!String.IsNullOrEmpty(ext))
- {
- var filetype = filetypes.FirstOrDefault(kvp => kvp.Value.Contains(ext));
- if (filetype.Key != null) selectedFiletypes.Add(filetype.Key);
- }
- }
- }
-
- if (selectedFiletypes.Count > 0)
- {
- selectedFiletypes = selectedFiletypes.Distinct().ToList();
- var filetypeText = String.Join(" of ", selectedFiletypes.ToArray());
- descriptions.Add(String.Format(currentLanguagePack.ResultDescriptionFiletype, filetypeText));
- }
- }
-
- // Build the description with comma's and a conjunction ('and') between the last two.
- if (descriptions.Count > 0)
- {
- string result = currentLanguagePack.ResultDescriptionStart + " ";
-
- if (descriptions.Count > 1)
- {
- result += String.Join(", ", descriptions.GetRange(0, descriptions.Count - 1).ToArray());
- result += currentLanguagePack.ResultDescriptionConjunction + descriptions.Last();
- }
- else
- {
- result += descriptions[0];
- }
-
- result += ".";
-
- return result;
- }
- else
- {
- return String.Empty;
- }
- }
-
- public static List<string> SplitAs_qParametersString(string as_q)
- {
- if (!String.IsNullOrEmpty(as_q))
- {
- // The OR and AND are used with the 'filetype' parameter, so gotta keep them intact. Transform them here temporarily to avoid the '+' split below.
- as_q = as_q.Replace("+OR+", "_OR_").Replace("+AND+", "_AND_");
-
- var as_qParametersTemp = as_q.Split('+');
-
- var as_qParameters = new List<string>();
- foreach (var tempParam in as_qParametersTemp)
- {
- if (!String.IsNullOrEmpty(tempParam))
- {
- // Only separate terms that contain ':', else assume it was a second part of the previous term.
- // For example, when searching for 'inmeta:RootCategory=R6.6', the '.' in 'R6.6' will get replaced by a space because GSA can't handle periods.
- // It will become 'inmeta:RootCategory=R6+6'. Because we split on '+', that would give odd results. That's why we use ':' to check.
- if (tempParam.Contains(":"))
- {
- as_qParameters.Add(tempParam);
- }
- else
- {
- if (as_qParameters.Count > 0)
- as_qParameters[as_qParameters.Count - 1] += '+' + tempParam;
- else
- as_qParameters.Add(tempParam);
- }
- }
- }
-
- for (var i = 0; i < as_qParameters.Count; i++)
- {
- // Return OR and AND to original state
- as_qParameters[i] = as_qParameters[i].Replace("_OR_", "+OR+").Replace("_AND_", "+AND+");
-
- // MF: The GSA returns '=' encoded but '~' not. At the same time, it DOES require them both encoded when passing them to GSA. Fuck the GSA. And fuck their whole '+'/' '/'%20' thing too :P.
- as_qParameters[i] = as_qParameters[i].Replace("~", "%7E").Replace("+", "%20");
- }
- return as_qParameters.ToList();
- }
- return new List<string>();
- }
-
- #endregion
-
-
- #region Search Results & Facets
-
- private void GetResults(string QueryString)
- {
- XmlDocument xmlGoogleResults = new XmlDocument();
-
- var request = (HttpWebRequest)WebRequest.Create(QueryString);
- request.Headers.Add("Accept-Language", "nl");
- request.UseDefaultCredentials = true;
-
- string responseFromServer;
- using (var response = request.GetResponse())
- {
- using (var stream = new System.IO.StreamReader(response.GetResponseStream(), Encoding.UTF8))
- {
- responseFromServer = stream.ReadToEnd();
- }
- }
-
- xmlGoogleResults.LoadXml(responseFromServer);
-
- RenderFacets(xmlGoogleResults);
-
- //Set results xslt
- string xsltFileLocation = string.Empty;
- xsltFileLocation = HttpContext.Current.Server.MapPath(GOOGLE_RESULTS_XSLT_NL);
-
- //var searchresults = XMLTransformer.TransformXMLToXHTML(xmlGoogleResults, xsltFileLocation);
- var searchresults = XMLTransformer.TransformXMLToXHTML_RespectDisableOutputEscaping(xmlGoogleResults, xsltFileLocation);
-
- //this.SearchResults.Text = HttpUtility.HtmlDecode(searchresults);
- this.SearchResults.Text = searchresults;
-
- //Fix Google links to Categories
- this.SearchResults.Text = this.SearchResults.Text.Replace("%5C", "\\");
- }
-
- private void RenderFacets(XmlDocument xmlSearchResults)
- {
- this.FacetsHeaderLiteral.Text = String.Format("<div class=\"resultheader\">{0}</div>", currentLanguagePack.FacetsTitle);
-
- // Collections string format example: 'IenM:staging-1ntra|Kennisplein:Kennisplein'
- var collections = new Dictionary<string, string>();
- if (!String.IsNullOrEmpty(this.currentLanguagePack.Collections))
- {
- var pairs = this.currentLanguagePack.Collections.Split('|');
- foreach (var pair in pairs)
- {
- var col = pair.Split(':');
- collections.Add(col[0], col[1]);
- }
- }
-
- // 'as_q' parameter, split on '+'
- List<string> as_qParameters = new List<string>();
- if (xmlSearchResults.SelectSingleNode("/GSP/PARAM[@name='as_q']") != null)
- {
- as_qParameters = SplitAs_qParametersString(xmlSearchResults.SelectSingleNode("/GSP/PARAM[@name='as_q']").Attributes["original_value"].Value);
- }
-
- // Rest of the search url without the 'as_q' parameter
- var urlWithoutAs_q = CreateSearchUrl(xmlSearchResults, "as_q");
-
-
-
- var searchQuerystring = new SearchQuerystring();
-
- XmlNodeList searchParams = xmlSearchResults.SelectNodes("/GSP/PARAM");
- if (searchParams != null)
- {
- foreach (XmlNode param in searchParams)
- {
- string name = param.Attributes["name"].Value;
- if (name != "start" && name != "swrnum" && !name.Contains("metabased_") && name != "dnavs")
- {
- string value = param.Attributes["original_value"].Value;
- if (name == "as_q")
- searchQuerystring.SetParamAs_q(SplitAs_qParametersString(value));
- else
- searchQuerystring.SetParam(name, value);
- }
- }
- }
-
-
- // MF: Changed sitecollection facet to use new SearchQuerystring class, for better control over adding and removing params.
- // If it works it might be better to convert the other facets too, so they also use the SearchQuerystring class.
- //facets.Add(CreateSiteCollectionFacet(xmlSearchResults, collections));
-
- //If theres only one collection there's no point in being able to filter on the same collection
- if (collections.Count > 1)
- {
- facets.Add(CreateSiteCollectionFacet(searchQuerystring, collections));
- }
-
- facets.AddRange(CreateMetadataFacets(xmlSearchResults, as_qParameters, urlWithoutAs_q));
- facets.Add(CreateDateFacet(as_qParameters, urlWithoutAs_q));
- facets.Add(CreateFiletypeFacet(as_qParameters, urlWithoutAs_q));
-
- foreach (var facet in facets)
- {
- switch (facet.Name)
- {
- case "PageType":
- case "RootCategory":
- facetsIntranet.Add(facet);
- break;
-
- case "kp:kennistype":
- facetsKennisplein.Add(facet);
- break;
-
- default:
- facetsGeneral.Add(facet);
- break;
- }
- }
-
- var haveSearchResults = (xmlSearchResults.SelectNodes("/GSP/RES").Count > 0);
-
- if (haveSearchResults || facetsGeneral.Any(f => f.Values.Any(v => v.Selected)))
- Filters.Text = String.Format("<div class=\"facetBlock\"><h4>{0}</h4>{1}</div>", currentLanguagePack.FacetsGeneralTitle, RenderFacetsHtml(facetsGeneral, haveSearchResults));
- else
- Filters.Visible = false;
-
- var siteCollectionFacet = facets.Find(f => f.Name == "SiteCollection");
-
- //Now Using lang pack values for Pretty names
-
- //var intranetIenMSelected = (siteCollectionFacet != null && siteCollectionFacet.Values.Any(v => v.PrettyLabel == "Intranet IenM" && v.Selected));
- //var kennispleinSelected = (siteCollectionFacet != null && siteCollectionFacet.Values.Any(v => v.PrettyLabel == "Kennisplein" && v.Selected));
- var intranetIenMSelected = (siteCollectionFacet != null && siteCollectionFacet.Values.Any(v => v.PrettyLabel == currentLanguagePack.FacetsIntranetTitle && v.Selected));
- var kennispleinSelected = (siteCollectionFacet != null && siteCollectionFacet.Values.Any(v => v.PrettyLabel == currentLanguagePack.FacetsKennispleinTitle && v.Selected));
-
- if (facetsIntranet.Count > 0 && intranetIenMSelected && (haveSearchResults || facetsIntranet.Any(f => f.Values.Any(v => v.Selected))))
- FiltersIntranet.Text = String.Format("<div class=\"facetBlock\"><h4>{0}</h4>{1}</div>", currentLanguagePack.FacetsIntranetTitle, RenderFacetsHtml(facetsIntranet, haveSearchResults));
- else
- IenMWrapper.Visible = false;
-
- if (facetsKennisplein.Count > 0 && kennispleinSelected && (haveSearchResults || facetsKennisplein.Any(f => f.Values.Any(v => v.Selected))))
- FiltersKennisplein.Text = String.Format("<div class=\"facetBlock\"><h4>{0}</h4>{1}</div>", currentLanguagePack.FacetsKennispleinTitle, RenderFacetsHtml(facetsKennisplein, haveSearchResults));
- else
- KennispleinWrapper.Visible = false;
-
- if (Filters.Visible == false && FiltersIntranet.Visible == false && FiltersKennisplein.Visible == false)
- FacetColumn.Style.Add("visibility", "hidden");
- }
-
- private static string CreateSearchUrl(XmlDocument xdoc, params string[] skipParameters)
- {
- XmlNodeList searchParams = xdoc.SelectNodes("/GSP/PARAM");
- StringBuilder link = new StringBuilder();
-
- if (searchParams != null)
- {
- foreach (XmlNode param in searchParams)
- {
- string name = param.Attributes["name"].Value;
- if (name != "start" && name != "swrnum" && !name.Contains("metabased_") && name != "dnavs" && !skipParameters.Contains(name))
- {
- string value = param.Attributes["original_value"].Value;
- link.Append(string.Format("{0}={1}", name, value));
- link.Append("&");
- }
- }
- }
-
- return link.ToString();
- }
-
- //private Facet CreateSiteCollectionFacet(XmlDocument xmlSearchResults, Dictionary<string, string> collections)
- private Facet CreateSiteCollectionFacet(SearchQuerystring searchQuerystring, Dictionary<string, string> collections)
- {
- // 'site' parameter
- //string siteParameter = null;
- //if (xmlSearchResults.SelectSingleNode("/GSP/PARAM[@name='site']") != null)
- // siteParameter = xmlSearchResults.SelectSingleNode("/GSP/PARAM[@name='site']").Attributes["value"].Value;
-
- // Rest of the search url without the 'as_q' parameter
- //var urlWithoutSiteCollection = CreateSearchUrl(xmlSearchResults, "site");
- //var urlWithoutSiteCollection = CreateSearchUrl(xmlSearchResults, "site");
-
- // Create facet
- var siteFacet = new Facet("SiteCollection", currentLanguagePack.FacetSourceHeader, null);
- siteFacet.Values = new List<FacetValue>();
- foreach (var collection in collections)
- {
- siteFacet.Values.Add(new FacetValue(collection.Key, collection.Value));
- }
-
- // Any selected values?
- var site = searchQuerystring.GetParamValue("site");
- bool facetSelected = false;
- foreach (var value in siteFacet.Values)
- {
- value.Selected = String.Equals(site, value.Value, StringComparison.OrdinalIgnoreCase);
-
- if (value.Selected)
- {
- facetSelected = true;
- break;
- }
- }
-
- // Set urls for toggling facet values on / off
- var localQuerystring = searchQuerystring.Copy();
- if (facetSelected)
- {
- siteFacet.Values.RemoveAll(v => !v.Selected);
-
- localQuerystring.RemoveParam("site");
-
- // Hardcoded linked facets for now... also matched on their PrettyLabel which is not elegant either.
- // TODO: add to LanguagePack or Setting or something
-
- // Now using lang pack values for pretty labels
-
- //if (siteFacet.Values[0].PrettyLabel == "Intranet IenM")
- if (siteFacet.Values[0].PrettyLabel == currentLanguagePack.FacetsIntranetTitle)
- {
- localQuerystring.RemoveAs_qParam("inmeta:PageType");
- localQuerystring.RemoveAs_qParam("inmeta:RootCategory");
- }
- //else if (siteFacet.Values[0].PrettyLabel == "Kennisplein")
- else if (siteFacet.Values[0].PrettyLabel == currentLanguagePack.FacetsKennispleinTitle)
- {
- localQuerystring.RemoveAs_qParam("inmeta:kp%253Akennistype");
- }
-
- foreach (var value in siteFacet.Values)
- {
- value.Url = "?" + localQuerystring.ToString();
- }
- }
- else
- {
- foreach (var value in siteFacet.Values)
- {
- localQuerystring.SetParam("site", value.Value);
- value.Url = String.Format("?" + localQuerystring.ToString());
- }
- }
-
-
- return siteFacet;
- }
-
- private List<Facet> CreateMetadataFacets(XmlDocument xmlSearchResults, List<string> as_qParameters, string urlWithoutAs_q)
- {
- var facets = new List<Facet>();
-
- var metadataFacetNodes = xmlSearchResults.SelectNodes("/GSP/RES/PARM/PMT");
- foreach (XmlNode metadataFacetNode in metadataFacetNodes)
- {
- // Create facet (example: 'TargetGroup')
- var facet = new Facet()
- {
- Name = metadataFacetNode.Attributes["NM"].Value,
- PrettyLabel = metadataFacetNode.Attributes["DN"].Value,
- QueryPrefix = "inmeta",
- Values = new List<FacetValue>()
- };
-
- if (facet.Name == "dc:language")
- {
- facet = CreateLanguageFacet(xmlSearchResults, metadataFacetNode, facet);
- }
- else
- {
- // Add possible values (examples: 'SSO', 'IVW', 'VenW', ..)
- foreach (XmlNode facetValueNode in metadataFacetNode.SelectNodes("PV"))
- {
- var facetValue = new FacetValue()
- {
- Value = facetValueNode.Attributes["V"].Value,
- PrettyLabel = facetValueNode.Attributes["V"].Value,
- Count = Int32.Parse(facetValueNode.Attributes["C"].Value)
- };
-
- //if (facet.Name == "dc:language") facetValue.PrettyLabel = LanguageCodesToPrettyText(facetValue.PrettyLabel);
-
- string as_qItem = String.Empty;
-
- // If queryprefix contains column it needs to be double-escaped. Whyyyyyy...
- if (facet.Name.Contains(":"))
- {
- as_qItem = facet.QueryPrefix + ":" + CustomUrlEncode(CustomUrlEncode(facet.Name) + "=" + CustomUrlEncode(facetValue.Value));
- }
- else
- {
- // Periods (.) also require some custom businesslogic.
- if (facetValue.Value.Contains('.'))
- {
- as_qItem = facet.QueryPrefix + ":" + CustomUrlEncode(facet.Name + "~" + CustomUrlEncode(facetValue.Value).Replace(".", " "));
- }
- else
- {
- as_qItem = facet.QueryPrefix + ":" + CustomUrlEncode(facet.Name + "=" + CustomUrlEncode(facetValue.Value));
- }
- }
-
- as_qItem = DecodeUnicodeChars(as_qItem, false);
-
- // Currently selected?
- facetValue.Selected = as_qParameters.Contains(as_qItem, StringComparer.OrdinalIgnoreCase);
-
- // Search url for toggling this filter on/off
- var localAs_qParameters = as_qParameters.ToList();
- if (facetValue.Selected)
- localAs_qParameters.RemoveAll(p => String.Equals(p, as_qItem, StringComparison.OrdinalIgnoreCase));
- else
- localAs_qParameters.Add(as_qItem);
-
- facetValue.Url = String.Format("?{0}as_q={1}", urlWithoutAs_q, DecodeUnicodeChars(String.Join(" ", localAs_qParameters.ToArray()), true));
-
- facet.Values.Add(facetValue);
- }
- }
-
- facets.Add(facet);
- }
-
- return facets;
- }
-
- private Facet CreateLanguageFacet(XmlDocument xmlSearchResults, XmlNode metadataFacetNode, Facet facet)
- {
- // Add the possible languagefacet values & their counts. Split values like 'en fr' into 'en' and 'fr'.
- foreach (XmlNode facetValueNode in metadataFacetNode.SelectNodes("PV"))
- {
- // Examples: 'en', 'fr', 'nl en'
- var value = facetValueNode.Attributes["V"].Value;
- if (value != null) value = value.Trim().ToLower();
-
- var languageCodes = value.Split(' ');
- foreach (var languageCode in languageCodes)
- {
- var count = Int32.Parse(facetValueNode.Attributes["C"].Value);
-
- var existingValue = facet.Values.Find(fv => fv.Value == languageCode);
- if (existingValue != null) // If already exists, just add the count.
- {
- existingValue.Count += count;
- }
- else // Else add a new language.
- {
- facet.Values.Add(new FacetValue()
- {
- Value = languageCode,
- PrettyLabel = LanguageCodesToPrettyText(languageCode),
- Count = count
- });
- }
- }
- }
-
- // Get current partialfields param and create a url without it.
- string partialfields = String.Empty;
- if (xmlSearchResults.SelectSingleNode("/GSP/PARAM[@name='partialfields']") != null)
- partialfields = xmlSearchResults.SelectSingleNode("/GSP/PARAM[@name='partialfields']").Attributes["original_value"].Value;
-
- var urlWithoutPartialFields = CreateSearchUrl(xmlSearchResults, "partialfields");
-
- // Extract the list of currently selected languages based on the partialfields param.
- var languageContainerPattern = new Regex(@"\((dc%253Alanguage.+?)\)\.?", RegexOptions.IgnoreCase);
- var languageContainerContents = String.Empty;
- var languagePattern = new Regex(@"dc%253Alanguage:([a-z]+)", RegexOptions.IgnoreCase);
- var selectedLanguages = new List<string>();
-
- var containerMatch = languageContainerPattern.Match(partialfields);
- if (containerMatch.Success)
- {
- languageContainerContents = containerMatch.Groups[1].Value;
- foreach (Match languageMatch in languagePattern.Matches(containerMatch.Value))
- {
- if (languageMatch != null && languageMatch.Groups.Count >= 2)
- {
- var language = languageMatch.Groups[1].Value;
- if (!String.IsNullOrEmpty(language))
- selectedLanguages.Add(language.Trim().ToLower());
- }
- }
- }
- selectedLanguages = selectedLanguages.Distinct().ToList();
-
- // Set Selected property for each language (facet value)
- foreach (var value in facet.Values)
- {
- value.Selected = selectedLanguages.Contains(value.Value);
- }
-
- // If any languages are selected, remove all non-selected languages.
- // This is to prevent odd looking (though still technically correct) filters when the search results contain pages that have multiple languages.
- if (selectedLanguages.Count > 0)
- {
- facet.Values.RemoveAll(fv => !fv.Selected);
- }
-
- // Go through each languagefacet value again and set the Url property (for toggling this facet value on/off).
- foreach (var value in facet.Values)
- {
- string newPartialFields;
- if (value.Selected)
- {
- var newSelectedLanguages = selectedLanguages.Where(lang => lang != value.Value);
- if (newSelectedLanguages.Count() > 0)
- {
- // Deselect this language, other languages still selected (example: 'en, fr' -> 'en')
- var newLangFilters = String.Join("|", newSelectedLanguages.Select(lang => "dc%253Alanguage:" + lang).ToArray());
- newPartialFields = partialfields.Replace(languageContainerContents, newLangFilters);
- }
- else
- {
- // Deselect this language, no other languages selected (example: 'en' -> '')
- newPartialFields = partialfields.Replace(containerMatch.Value, String.Empty);
- }
- }
- else
- {
- var newSelectedLanguages = selectedLanguages.ToList();
- newSelectedLanguages.Add(value.Value);
- if (newSelectedLanguages.Count() > 1)
- {
- // Select this language, other languages also selected (example: 'fr' -> 'fr, en')
- var newLangFilters = String.Join("|", newSelectedLanguages.Select(lang => "dc%253Alanguage:" + lang).ToArray());
- newPartialFields = partialfields.Replace(languageContainerContents, newLangFilters);
- }
- else
- {
- // Select this language, no other languages selected (example: '' -> 'en')
- newPartialFields = "(dc%253Alanguage:" + value.Value + ")";
- if (!String.IsNullOrEmpty(partialfields)) newPartialFields = partialfields + "." + newPartialFields;
- }
- }
-
- if (!String.IsNullOrEmpty(newPartialFields))
- value.Url = String.Format("?{0}partialfields={1}", urlWithoutPartialFields, DecodeUnicodeChars(newPartialFields, true));
- else
- value.Url = "?" + urlWithoutPartialFields;
- }
-
- return facet;
- }
-
- private Facet CreateDateFacet(List<string> as_qParameters, string urlWithoutAs_q)
- {
- //var dateFacet = new Facet("Date", "Datum", "daterange");
- var dateFacet = new Facet("Date", currentLanguagePack.FacetDateHeader, "inmeta:dc%253Adate");
-
- // Predefined facets
- dateFacet.Values = new List<FacetValue>();
- dateFacet.Values.Add(new FacetValue(currentLanguagePack.FacetDateDay, FormatDateTimeForGoogle(DateTime.Now.AddDays(-1)) + ".."));
- dateFacet.Values.Add(new FacetValue(currentLanguagePack.FacetDateWeek, FormatDateTimeForGoogle(DateTime.Now.AddDays(-7)) + ".."));
- dateFacet.Values.Add(new FacetValue(currentLanguagePack.FacetDateMonth, FormatDateTimeForGoogle(DateTime.Now.AddMonths(-1)) + ".."));
- dateFacet.Values.Add(new FacetValue(currentLanguagePack.FacetDateYear, FormatDateTimeForGoogle(DateTime.Now.AddYears(-1)) + ".."));
-
- List<string> newAs_qParameters = null; // this variable is used multiple times below, didn't want to keep thinking up different variable names... :-P
-
- // Initialize the predefined facets
- foreach (var dateValue in dateFacet.Values)
- {
- // How this filter is represented in the 'as_q' parameter
- string newAs_q = dateFacet.QueryPrefix + ":" + dateValue.Value;
-
- // Currently selected?
- dateValue.Selected = as_qParameters.Contains(newAs_q, StringComparer.OrdinalIgnoreCase);
-
- // Search url for toggling this filter on/off
- newAs_qParameters = as_qParameters.ToList();
- if (dateValue.Selected)
- newAs_qParameters.RemoveAll(p => String.Equals(p, newAs_q, StringComparison.OrdinalIgnoreCase));
- else
- newAs_qParameters.Add(newAs_q);
- dateValue.Url = String.Format("?{0}as_q={1}", urlWithoutAs_q, String.Join(" ", newAs_qParameters.ToArray()));
- }
-
- // Any predefined facets selected? Then we're already done!
- var selectedFacetValue = dateFacet.Values.Find(fv => fv.Selected == true);
- if (selectedFacetValue != null)
- {
- // Remove all but the selected item
- dateFacet.Values.Clear();
- dateFacet.Values.Add(selectedFacetValue);
-
- return dateFacet;
- }
- // Else we need to add / check for a custom date range facet
- else
- {
- var customRangeValue = new FacetValue("DateCustomRange", null);
-
- // Is a custom range selected?
- var selectedCustomRangeFacetValue = as_qParameters.Find(p => p.IndexOf(dateFacet.QueryPrefix + ":") == 0);
- if (selectedCustomRangeFacetValue != null)
- {
- dateFacet.Values.Clear();
- dateFacet.Values.Add(customRangeValue);
-
- customRangeValue.Selected = true;
- customRangeValue.Value = selectedCustomRangeFacetValue.Substring(selectedCustomRangeFacetValue.IndexOf(":") + 1);
-
- newAs_qParameters = as_qParameters.ToList();
- newAs_qParameters.Remove(selectedCustomRangeFacetValue);
- customRangeValue.Url = String.Format("?{0}as_q={1}", urlWithoutAs_q, String.Join(" ", newAs_qParameters.ToArray()));
- }
- else
- {
- customRangeValue.Selected = false;
- customRangeValue.Value = String.Empty;
-
- newAs_qParameters = as_qParameters.ToList();
- newAs_qParameters.Add(dateFacet.QueryPrefix + ":{0}..{1}");
- customRangeValue.Url = String.Format("?{0}as_q={1}", urlWithoutAs_q, String.Join(" ", newAs_qParameters.ToArray()));
-
- dateFacet.Values.Add(customRangeValue);
- }
-
- return dateFacet;
- }
- }
-
- private Facet CreateFiletypeFacet(List<string> as_qParameters, string urlWithoutAs_q)
- {
- var filetypeFacet = new Facet("Filetype", currentLanguagePack.FacetFiletypeHeader, "ext");
-
- filetypeFacet.Values = new List<FacetValue>();
- foreach (var kvp in filetypes)
- {
- filetypeFacet.Values.Add(new FacetValue(kvp.Key, kvp.Value));
- }
-
- // Get currently selected filetype extensions
- var selectedFiletypeExtensions = new List<string>();
- var filetypeAs_qParam = as_qParameters.Find(p => p.StartsWith("ext", StringComparison.OrdinalIgnoreCase));
- if (filetypeAs_qParam != null)
- {
- var filetypeMatches = new Regex("ext:([a-z]+)", RegexOptions.IgnoreCase).Matches(filetypeAs_qParam);
- foreach (Match match in filetypeMatches)
- {
- if (match != null && match.Groups != null && match.Groups.Count >= 2 && !String.IsNullOrEmpty(match.Groups[1].Value))
- {
- selectedFiletypeExtensions.Add(match.Groups[1].Value.ToLower());
- }
- }
- }
-
- // Iterate over all facet values (Word, Excel, ...) and set their Selected property
- foreach (var value in filetypeFacet.Values)
- {
- value.Selected = true;
-
- // Iterate over all extensions in a facet value (Word: doc, docx. ...)
- var extensions = value.Value.Split(';');
- for (var i = 0; i < extensions.Length; i++)
- {
- // If any of the extensions in this facet value do not appear in the selected extensions, it isn't selected.
- if (!selectedFiletypeExtensions.Any(ext => String.Equals(ext, extensions[i], StringComparison.OrdinalIgnoreCase)))
- {
- value.Selected = false;
- }
- }
- }
-
- // If we selected a facet value, remove the others
- if (filetypeFacet.Values.Any(v => v.Selected))
- {
- filetypeFacet.Values.RemoveAll(v => !v.Selected);
- }
-
- foreach (var value in filetypeFacet.Values)
- {
- var extensions = value.Value.Split(';');
-
- // Prepare list of extensions to use in facet value toggle url below
- var localSelectedFiletypeExtensions = new List<string>(selectedFiletypeExtensions);
- if (value.Selected)
- localSelectedFiletypeExtensions.RemoveAll(ext => extensions.Contains(ext));
- else
- localSelectedFiletypeExtensions.AddRange(extensions);
-
- var localAs_qParameters = as_qParameters.ToList();
- localAs_qParameters.Remove(filetypeAs_qParam);
-
- var newFiletypeAs_qParam = String.Join("%20OR%20", localSelectedFiletypeExtensions.Select(ext => "ext:" + ext).ToArray());
-
- localAs_qParameters.Add(newFiletypeAs_qParam);
-
- value.Url = String.Format("?{0}as_q={1}", urlWithoutAs_q, String.Join(" ", localAs_qParameters.ToArray()));
- }
-
- return filetypeFacet;
- }
-
- private string RenderFacetsHtml(List<Facet> facets, bool haveSearchResults)
- {
- StringBuilder html = new StringBuilder();
-
- //Only show Header if we have facets
- if (facets.Count > 0)
- {
- //html.Append("<div class=\"resultheader\" style=\"background-color: #DEEBE3;\"><div style=\"padding-left: 19px;\"><strong>Verfijn uw resultaten</strong></div></div>");
- }
-
- foreach (var facet in facets)
- {
- // If we don't have any search results AND none of the values of this facet are selected, don't show/render it.
- if (!haveSearchResults && !facet.Values.Any(v => v.Selected)) continue;
-
- html.Append("<div class=\"facet\">");
- html.Append(string.Format("<div class=\"facetheader\">{0}</div>", facet.PrettyLabel));
- html.AppendLine();
-
- html.AppendLine("<ul class=\"facetlist\">");
- int nodecount = 0;
- foreach (var facetValue in facet.Values.OrderBy(v => !v.Selected).ThenByDescending(v => v.Count))
- {
- if (!(facet.Name == "Date" && facetValue.PrettyLabel == "DateCustomRange"))
- {
- if (facetValue.Selected)
- {
- html.Append(string.Format(
- "<li class=\"facetitemselected\"><a href=\"{0}\" style=\"text-decoration:none;\">{1}<div class=\"facetdelete\"></div></a></li>",
- facetValue.Url, facetValue.PrettyLabel
- ));
- }
- else
- {
- html.Append(string.Format(
- "<li class=\"facetitem\"><a href=\"{0}\" style=\"text-decoration:none;\">{1}</a> {2}</li>",
- facetValue.Url, facetValue.PrettyLabel, facetValue.Count >= 0 ? "(" + facetValue.Count + ")" : String.Empty
- ));
- }
- nodecount++;
- }
- }
-
- if (facet.Name == "Date")
- {
- var customRangeFacetValue = facet.Values.Find(v => v.PrettyLabel == "DateCustomRange");
- if (customRangeFacetValue != null)
- {
- if (customRangeFacetValue.Selected)
- {
- string dateFrom = String.Empty, dateTo = String.Empty;
- var datePattern = new Regex(@"(\d{4}-\d{1,2}-\d{1,2})?\.\.(\d{4}-\d{1,2}-\d{1,2})?");
- var match = datePattern.Match(customRangeFacetValue.Value ?? String.Empty);
- if (match != null && match.Groups != null && match.Groups.Count >= 3)
- {
- var yearMonthDay = new Regex(@"(\d{4})-(\d{1,2})-(\d{1,2})");
- dateFrom = yearMonthDay.Replace(match.Groups[1].Value, @"$3-$2-$1");
- dateTo = yearMonthDay.Replace(match.Groups[2].Value, @"$3-$2-$1");
- }
-
- string selectedDateText = String.Empty;
- if (!String.IsNullOrEmpty(dateFrom) && !String.IsNullOrEmpty(dateTo))
- selectedDateText = dateFrom + " tot " + dateTo;
- else if (!String.IsNullOrEmpty(dateFrom))
- selectedDateText += "Vanaf " + dateFrom;
- else if (!String.IsNullOrEmpty(dateTo))
- selectedDateText += "Tot " + dateTo;
-
- html.AppendLine(String.Format(
- "<li class=\"facetitemselected\"><a href=\"{0}\" style=\"text-decoration:none;\">{1}<div class=\"facetdelete\"></div></a></li>",
- customRangeFacetValue.Url, selectedDateText
- ));
- }
- else
- {
- html.AppendLine(String.Format(@"<li class='datefilter'>
- <input type='hidden' id='DateFacetUrl' value='{0}' />
- <div>{1}</div>
- <div>
- <input id='DateFacetFrom' type='text' class='inputdate' /><span> - </span>
- <input id='DateFacetTo' type='text' class='inputdate' />
- <input id='DateFacetButton' type='button' value='{2}' class='datefilterbutton' />
- </div>
- </li>",
- customRangeFacetValue.Url, currentLanguagePack.FacetDateChooseRange, currentLanguagePack.FacetDateConfirmRange
- ));
- }
- }
- }
- html.AppendLine("</ul>");
-
- if (nodecount > 8) html.AppendLine("<span class='toggleFacets'> </span>");
-
- html.AppendLine("</div>");
- }
-
- return html.ToString();
- }
-
- private static Dictionary<string, string> filetypes = new Dictionary<string, string>()
- {
- { "Word", "doc;docx" },
- { "Excel", "xls;xlsx" },
- { "Powerpoint", "ppt;pptx" },
- { "PDF", "pdf" }
- };
-
- // TODO: Languagepack, or better suited for upcoming Settings table?
- // Also, 'xx' -> 'Overig' is quick & dirty way to deal with problem of the 'xx' language code.
- private static Dictionary<string, string> languageCodesToPrettyName = new Dictionary<string, string>() {
- { "en", "Engels" },
- { "nl", "Nederlands" },
- { "de", "Duits" },
- { "fr", "Frans" },
- { "it", "Italiaans" },
- { "es", "Spaans" },
- { "xx", "Overig" }
- };
- private string LanguageCodesToPrettyText(string languageCode)
- {
- // Need dutch names... don't think we can use RegionInfo for that :(. So let's use hardcoded Dictionary...
- if (!String.IsNullOrEmpty(languageCode))
- {
- languageCode = languageCode.Trim();
- var prettyNames = new List<string>();
-
- foreach (var code in languageCode.Split(' '))
- {
- if (!String.IsNullOrEmpty(code))
- {
- if (languageCodesToPrettyName.ContainsKey(code))
- prettyNames.Add(languageCodesToPrettyName[code]);
- else
- prettyNames.Add(code);
- }
- }
-
- return String.Join(" ", prettyNames.ToArray());
- }
- else
- {
- //return "Onbekend";
- return currentLanguagePack.FacetLanguageUnknown;
- }
- }
-
- #endregion
-
-
- #region Util
-
- /// <summary>
- /// Decodes any encoded unicode chars, for example "%u00eb" -> "ë".
- /// Also can decode double encoded unicode chars, for example "%25u00eb".
- /// </summary>
- public static string DecodeUnicodeChars(string str, bool decodeTwice)
- {
- var unicodePatterns = new List<Regex>()
- {
- new Regex("%(25)?u[0-9a-f]{4}", RegexOptions.IgnoreCase),
- new Regex("%(25)?[0-9a-f]{2}%(25)?[0-9a-f]{2}", RegexOptions.IgnoreCase)
- };
-
- foreach (var pattern in unicodePatterns)
- {
- foreach (Match match in pattern.Matches(str))
- {
- var decodedMatch = HttpUtility.UrlDecode(match.Value.ToLower());
- if (decodeTwice) decodedMatch = HttpUtility.UrlDecode(decodedMatch);
-
- str = str.Replace(match.Value, decodedMatch);
- }
- }
-
- return str;
- }
-
- public static Dictionary<string, string> QuerystringToDictionary(HttpRequest request)
- {
- var dict = new Dictionary<string, string>();
-
- if (request != null && request.QueryString != null)
- {
- foreach (var key in request.QueryString.AllKeys)
- {
- if (key != null) dict.Add(key, request.QueryString[key]);
- }
- }
-
- //if (!String.IsNullOrEmpty(querystring))
- //{
- // if (querystring.StartsWith("?")) querystring = querystring.Substring(1);
- // var parameters = querystring.Split('&');
- // foreach (var param in parameters)
- // {
- // var kvp = param.Split('=');
- // dict[kvp[0]] = kvp.Length > 1 ? kvp[1] : String.Empty;
- // }
- //}
-
- return dict;
- }
-
- public static string DictionaryToQuerystring(Dictionary<string, string> dict)
- {
- string qs = String.Empty;
-
- if (dict != null)
- {
- var parameters = dict.Select(kvp => kvp.Key + "=" + CustomUrlEncode(kvp.Value)).ToArray();
- qs = String.Join("&", parameters);
- }
-
- return qs;
- }
-
- public static string CustomUrlEncode(string str)
- {
- str = HttpUtility.UrlEncode(str);
- str = str.Replace("+", "%20").Replace("-", "%2D");
- str = UpperCaseEncode(str);
-
- return str;
- }
-
- public static string UpperCaseEncode(string value)
- {
- char[] lcencode = value.ToCharArray();
-
- for (int i = 0; i < lcencode.Length - 2; i++)
- {
- if (lcencode[i] == '%')
- {
- lcencode[i + 1] = char.ToUpper(lcencode[i + 1]);
- lcencode[i + 2] = char.ToUpper(lcencode[i + 2]);
- }
- }
-
- return new string(lcencode);
- }
-
- /// <summary>
- /// Reverses a date string from YYYY-MM-DD to DD-MM-YYYY.
- /// </summary>
- public static string ReverseDateString(string date)
- {
- var pattern = new Regex(@"(\d{4})-(\d{1,2})-(\d{1,2})", RegexOptions.IgnoreCase);
- var match = pattern.Match(date);
- if (match != null && match.Groups != null && match.Groups.Count >= 3)
- {
- return match.Groups[3] + "-" + match.Groups[2] + "-" + match.Groups[1];
- }
-
- return String.Empty;
- }
-
- private static string FormatDateTimeForGoogle(DateTime dt)
- {
- return dt.Year + "-" + dt.Month + "-" + dt.Day;
- }
-
- #endregion
- }
-
- class Facet
- {
- public string PrettyLabel;
- public string Name;
- public string QueryPrefix;
-
- public List<FacetValue> Values;
-
- public Facet() { }
- public Facet(string name, string label, string queryPrefix)
- {
- this.Name = name;
- this.PrettyLabel = label;
- this.QueryPrefix = queryPrefix;
- }
- }
-
- class FacetValue
- {
- public string PrettyLabel;
- public string Value;
- public int Count = -1;
- public bool Selected = false;
- public string Url;
-
- public FacetValue() { }
- public FacetValue(string label, string value)
- {
- this.PrettyLabel = label;
- this.Value = value;
- }
- }
-
- class SearchQuerystring
- {
- // Parameters that only have 1 facet linked to them, e.g. the parameter 'site' is only used by the facet 'SiteCollection'
- private List<SinglepartParam> singleParams = new List<SinglepartParam>();
-
- // The 'as_q' parameter has multiple facets linked to it, like the Date facet and Filetype facet.
- // Example: 'as_q=inmeta:dc%253Adate:2011-10-26..%20ext:pdf'
- private MultipartParam as_qMultiParam;
-
- public string GetParamValue(string paramName)
- {
- var existingParam = this.singleParams.Find(p => String.Equals(p.paramName, paramName, StringComparison.OrdinalIgnoreCase));
- if (existingParam != null)
- {
- return existingParam.paramValue;
- }
- return null;
- }
-
- public void SetParam(string paramName, string paramValue)
- {
- var existingParam = this.singleParams.Find(p => String.Equals(p.paramName, paramName, StringComparison.OrdinalIgnoreCase));
- if (existingParam != null)
- {
- existingParam.paramValue = paramValue;
- }
- else
- {
- this.singleParams.Add(new SinglepartParam()
- {
- paramName = paramName,
- paramValue = paramValue
- });
- }
- }
-
- public void RemoveParam(string paramName)
- {
- this.singleParams.RemoveAll(p => String.Equals(p.paramName, paramName, StringComparison.OrdinalIgnoreCase));
- }
-
- public void SetParamAs_q(List<string> paramValues)
- {
- this.as_qMultiParam = new MultipartParam()
- {
- paramName = "as_q",
- paramValues = paramValues
- };
- }
-
- public void RemoveAs_qParam(string paramValue)
- {
- if (this.as_qMultiParam != null)
- {
- this.as_qMultiParam.paramValues.RemoveAll(p => p.StartsWith(paramValue, StringComparison.OrdinalIgnoreCase));
- }
- }
-
- public override string ToString()
- {
- var querystringParams = new List<string>();
-
- foreach (var p in singleParams)
- {
- querystringParams.Add(p.paramName + "=" + p.paramValue);
- }
-
- if (as_qMultiParam != null && as_qMultiParam.paramValues != null)
- {
- var as_qValue = String.Join(" ", as_qMultiParam.paramValues.ToArray());
- if (!String.IsNullOrEmpty(as_qValue)) querystringParams.Add("as_q=" + as_qValue);
- }
-
- return String.Join("&", querystringParams.ToArray());
- }
-
- public SearchQuerystring Copy()
- {
- var copy = new SearchQuerystring();
-
- if (this.singleParams != null)
- {
- foreach (var i in singleParams)
- {
- copy.singleParams.Add(i.Copy());
- }
- }
-
- if (this.as_qMultiParam != null) copy.as_qMultiParam = this.as_qMultiParam.Copy();
-
- return copy;
- }
- }
-
- [DebuggerDisplay("{paramName} = {paramValue}")]
- class SinglepartParam
- {
- public string paramName;
- public string paramValue;
-
- public SinglepartParam Copy()
- {
- return new SinglepartParam()
- {
- paramName = this.paramName,
- paramValue = this.paramValue
- };
- }
- }
-
- class MultipartParam
- {
- public string paramName;
- public List<string> paramValues = new List<string>();
-
- public MultipartParam Copy()
- {
- var copy = new MultipartParam();
- copy.paramName = paramName;
- if (paramValues != null)
- {
- copy.paramValues = new List<string>(paramValues);
- }
- return copy;
- }
- }
- }