//------------------------------------------------------------------------------ // // Copyright (c) Telligent Systems Corporation. All rights reserved. // //------------------------------------------------------------------------------ using System; using System.Collections; using System.Collections.Specialized; using System.Text.RegularExpressions; using System.Web; using System.Web.Caching; using System.Xml; using CommunityServer.Configuration; using System.Text; namespace CommunityServer.Components { public class SiteUrls { public static readonly string SiteUrlsProviderName = "SiteUrlsProvider"; #region Initializer /// /// Returns a intance of SiteUrls. We first check the cache and if not found /// we parse the SiteUrls.config file and build it. /// /// public static SiteUrls Instance() { const string cacheKey = "SiteUrls"; SiteUrls siteUrls = CSCache.Get(cacheKey) as SiteUrls; if(siteUrls == null) { try { HttpContext Context = HttpContext.Current; CSConfiguration config = CSConfiguration.GetConfig(); Provider siteUrlProvider = config.Providers["SiteUrlsDataProvider"] as Provider; if(siteUrlProvider == null) { if(Context != null) { Context.Response.Write("

SiteUrl Provider was NOT found!

"); Context.Response.Write("A provider named SiteUrlsDataProvider with the type or derived type of CommunityServer.Components.SiteUrlsData, CommunityServer.Components must be added to the provider list"); Context.Response.End(); } else { throw new CSException(CSExceptionType.SiteUrlDataProvider,"Could not load SiteUrlsProvider"); } } string file = CSContext.Current.PhysicalPath(siteUrlProvider.Attributes["path"]); // CSContext.Current.MapPath(Globals.ApplicationPath + siteUrlsXmlFile); Type type = Type.GetType(siteUrlProvider.Type); SiteUrlsData data = Activator.CreateInstance(type,new object[]{file}) as SiteUrlsData; // Create the instance for the provider, or fall back on the builtin one // Provider urlProvider = (Provider) CSConfiguration.GetConfig().Providers[SiteUrlsProviderName]; if(urlProvider != null) siteUrls = ApplicationUrls.CreateInstance(urlProvider, data) as SiteUrls; else siteUrls = new SiteUrls(data); CacheDependency dep = new CacheDependency(file); CSCache.Max(cacheKey, siteUrls, dep); CSEvents.PostConfigurationInitialized(siteUrls); } catch(Exception ex) { if (ex.InnerException != null && ex.InnerException is CSException) { throw ex.InnerException; } string message = "

" + ex.Message + "

"; Exception inner = ex.InnerException; while(inner != null) { message = string.Format("{0}

{1}

", message, inner.Message); inner = inner.InnerException; } CSException csex = new CSException(CSExceptionType.SiteUrlDataProvider,message,ex); CatastrophicMessage.Write(HttpContext.Current,csex,"[SiteUrlData]","SiteUrlData.htm"); } } return siteUrls; } #endregion #region Force Refresh public static void ForceRefresh() { const string cacheKey = "SiteUrls"; CSCache.Remove(cacheKey); } #endregion #region Member variables & constructor //CSContext forumContext = CSContext.Current; private SiteUrlsData urlData = null; // Constructor loads all the site urls from the SiteUrls.config file // or returns from the cache // // Updated 8/17/2004 by ScottW >> Moved Initializate to Static instance method // This should enable us to cache on instance of SiteUrls and not 3 unique collections public SiteUrls(SiteUrlsData data) { urlData = data; } public virtual string RawPath(string rawpath) { return urlData.FormatUrl(rawpath); } #endregion #region Who is online // Who is online // public virtual string WhoIsOnline { get { return urlData.FormatUrl("whoIsOnline"); } } #endregion #region Moderation // Moderation // public virtual string Moderate { get { return urlData.FormatUrl("moderate"); } } public virtual string ModerationHome { get { return urlData.FormatUrl("moderate_home"); } } public virtual string ModeratePostRedirect { get { return urlData.FormatUrl("moderate_Post_Redirect"); } } public virtual string ModeratePostDelete (int postID, string returnUrl) { return urlData.FormatUrl("moderate_Post_Delete", postID.ToString(), returnUrl ); } public virtual string ModeratePostEdit (int postID, string returnUrl) { return urlData.FormatUrl("moderate_Post_Edit", postID.ToString(), returnUrl ); } public virtual string ModeratePostMove (int postID, string returnUrl) { return urlData.FormatUrl("moderate_Post_Move", postID.ToString(), returnUrl ); } public virtual string ModerateThreadsMove(string threadIDs, string returnUrl) { return urlData.FormatUrl("moderate_Threads_Move", threadIDs, returnUrl); } public virtual string ModerateQuickThreadSplit (int postID) { return urlData.FormatUrl("moderate_Quick_Thread_Split", postID.ToString()); } public virtual string ModerateThreadSplit (int postID, string returnUrl) { return urlData.FormatUrl("moderate_Thread_Split", postID.ToString(), returnUrl ); } public virtual string ModerateQuickThreadJoin (int postID) { return urlData.FormatUrl("moderate_Quick_Thread_Join", postID.ToString()); } public virtual string ModerateThreadJoin (int postID, string returnUrl) { return urlData.FormatUrl("moderate_Thread_Join", postID.ToString(), returnUrl ); } public virtual string ModerationQuickHistory(int postID) { return urlData.FormatUrl("moderation_Quick_History", postID.ToString()); } public virtual string ModerationHistory (int postID) { return ModerationHistory( postID, null ); } public virtual string ModerationHistory (int postID, string returnUrl) { string outString = ""; if (Globals.IsNullorEmpty( returnUrl )) { outString = urlData.FormatUrl("moderation_History", postID.ToString(), ""); outString = outString.Replace( "&ReturnUrl=", "" ); } else { outString = urlData.FormatUrl("moderation_History", postID.ToString(), returnUrl); } return outString; } public virtual string ModerateForum (int forumID) { return urlData.FormatUrl("moderate_Forum", forumID.ToString()) ; } public virtual string UserModerationHistory (int userID) { return UserModerationHistory( userID, -1 ) ; } public virtual string UserModerationHistory (int userID, int action) { string outString = urlData.FormatUrl( "admin_User_ModerationHistory", userID.ToString(), action.ToString() ); if (action <= 0) { outString = outString.Replace( "&Action=" + action.ToString(), "" ); } return outString; } #endregion #region Control Panel // Control Panel General public virtual string ControlPanel { get { return urlData.FormatUrl("controlpanel"); } } public virtual string ControlPanelLoading(string message) { return urlData.FormatUrl("controlpanel_loading", Globals.UrlEncode(message)); } public virtual string ControlPanelRssCtrlManage() { return urlData.FormatUrl("tools_ControlPanel_RssCtrlManage"); } #region Membership Control Panel public virtual string ControlPanelMembershipHome { get { return urlData.FormatUrl("membership_ControlPanel_Home"); } } public virtual string ControlPanelUserAdd { get { return urlData.FormatUrl("membership_ControlPanel_UserAdd"); } } public virtual string ControlPanelUserEdit(int userID) { return urlData.FormatUrl("membership_ControlPanel_UserEdit", userID.ToString()); } public virtual string ControlPanelUserAddedMessage(int userID) { return urlData.FormatUrl("membership_ControlPanel_UserAddedMessage", userID.ToString()); } public virtual string ControlPanelUserRoles(int userID) { return urlData.FormatUrl("membership_ControlPanel_UserRoles", userID.ToString()); } public virtual string ControlPanelUserName(int userID) { return urlData.FormatUrl("membership_ControlPanel_UserName", userID.ToString()); } public virtual string ControlPanelUserPassword(int userID) { return urlData.FormatUrl("membership_ControlPanel_UserPassword", userID.ToString()); } public virtual string ControlPanelBrowseUsers { get { return urlData.FormatUrl("membership_ControlPanel_UsersBrowse"); } } public virtual string ControlPanelUserSearch_AccountStatus(UserAccountStatus statusFilter) { return urlData.FormatUrl("membership_ControlPanel_UserSearch_AccountStatus", (int)statusFilter); } public virtual string ControlPanelUserSearch_AccountStatus(Guid roleID) { return urlData.FormatUrl("membership_ControlPanel_UserSearch_Role", roleID.ToString()); } public virtual string ControlPanelManageRoles { get { return urlData.FormatUrl("membership_ControlPanel_Roles"); } } public virtual string ControlPanelRoleAdd { get { return urlData.FormatUrl("membership_ControlPanel_RoleAdd"); } } public virtual string ControlPanelRoleEdit(Guid roleID) { return urlData.FormatUrl("membership_ControlPanel_RoleEdit", roleID.ToString()); } #endregion #endregion #region Tags public virtual string TagsHome { get { return urlData.FormatUrl("tags_home"); } } public virtual string TagsBrowser(string[] tagNames) { StringBuilder sb = new StringBuilder(); foreach (string tag in tagNames) { if (sb.Length > 0) sb.Append("/"); sb.Append(Globals.UrlEncodePathComponent(tag)); } return urlData.FormatUrl("tags_browse", sb.ToString()); } #endregion public ArrayList Mappings { get { return urlData.Mappings;} } public virtual string ContentSelectorModal { get { return urlData.FormatUrl("ContentSelectorModal"); } } public virtual string TagSelectorModal (string TagEditorID) { return urlData.FormatUrl("tagselectormodal", TagEditorID); } public virtual string Favicon { get { return urlData.FormatUrl("favicon"); } } public virtual string Ink(InkData ink) { return urlData.FormatUrl("ink",ink.InkID,ink.DateUpdated.Ticks.ToString()); } public virtual string InkDll { get{ return urlData.FormatUrl("inkdll");} } #region KnowledgeBase #endregion #region Posts // Post related properties // /// /// If possible use Post (int postID, int forumID) /// public virtual string Post (int postID) { return urlData.FormatUrl("post", postID.ToString()); } public virtual string Post (int postID, PostViewType view) { return urlData.FormatUrl("post_WithTemporaryView", postID.ToString(), view.ToString()); } public virtual string PostRating (int postID) { return urlData.FormatUrl("post_Rating", postID.ToString()); } public virtual string PollVoteReport(int postID, ApplicationType applicationType) { return CSContext.Current.Context.Response.ApplyAppPathModifier(string.Format("~/ControlPanel/Tools/Reports/PollVotingReport.aspx?pid={0}&atid={1}", postID, (int) applicationType)); } #endregion #region Help public virtual string HelpThreadIcons { get { return urlData.FormatUrl("help_ThreadIcons", Globals.Language); } } #endregion #region User // User related properties // public virtual string UserBanned { get { return urlData.FormatUrl("user_Banned"); } } public virtual string UserProfile (string username) { return urlData.FormatUrl("user_ByUserName", Globals.UrlEncode(username)); } public virtual string UserProfile (int userID) { return urlData.FormatUrl("user", userID.ToString()); } public virtual string UserEditProfile { get { string currentPath = CSContext.Current.Context.Request.Url.PathAndQuery; string returnUrl = null; if (ExtractQueryParams(currentPath)["ReturnUrl"] != null) returnUrl = ExtractQueryParams(currentPath)["ReturnUrl"]; if ((returnUrl == null) || (returnUrl == string.Empty)) return urlData.FormatUrl("user_EditProfile", currentPath); else return urlData.FormatUrl("user_EditProfile", returnUrl); } } public virtual string CleanUserEditProfile { get { return urlData.FormatUrl("user_EditProfile_Clean");} } public virtual string UserMyForums { get { return urlData.FormatUrl("user_MyForums"); } } public virtual string UserChangePassword { get { return urlData.FormatUrl("user_ChangePassword"); } } public virtual string UserChangePasswordAnswer { get { return urlData.FormatUrl("user_ChangePasswordAnswer"); } } public virtual string UserForgotPassword { get { return urlData.FormatUrl("user_ForgotPassword"); } } public virtual string UserRegister { get { string currentPath = CSContext.Current.RawUrl; string returnUrl = null; if (ExtractQueryParams(currentPath)["ReturnUrl"] != null) returnUrl = ExtractQueryParams(currentPath)["ReturnUrl"]; if ((returnUrl == null) || (returnUrl == string.Empty)) return urlData.FormatUrl("user_Register", currentPath); else return urlData.FormatUrl("user_Register", returnUrl); } } public virtual string UserRegisterWithInvitation(Guid invitationKey) { return urlData.FormatUrl("user_Register_WithInvitation", invitationKey.ToString()); } public virtual string UserInvite { get { return urlData.FormatUrl("user_Invite"); } } public virtual string AcceptUserInvitation(Guid invitationKey) { return urlData.FormatUrl("user_AcceptInvitation", invitationKey.ToString()); } public virtual string UserList { get { return urlData.FormatUrl("user_List"); } } public virtual string UserRoles (string roleGuid) { return urlData.FormatUrl("user_Roles", roleGuid ); } #endregion #region Favorites public virtual string Favorite(ApplicationType applicationType, FavoriteType favoriteType, int itemID) { return urlData.FormatUrl("favorite", ((int)applicationType).ToString(), ((int)favoriteType).ToString(), itemID.ToString()); } #endregion #region Private Messages // Private Messages // public virtual string PrivateMessage (int userID) { return urlData.FormatUrl("privateMessage", userID.ToString()); } public virtual string UserPrivateMessages { get { return urlData.FormatUrl("privateMessages"); } } #endregion #region Email // Email // public virtual string EmailToUser (int userID) { return urlData.FormatUrl("email_ToUser", userID.ToString()); } #endregion #region Emoticon // Resolves the absolute path to emoticon images // public virtual string Emoticon { get { return urlData.FormatUrl("emoticons"); } } #endregion public virtual string LoadingImageUrl { get {return urlData.FormatUrl("loadingImage");} } public virtual string BlankPage { get {return urlData.FormatUrl("blankPage");} } #region RSS public virtual string AggView(int postid) { return urlData.FormatUrl("aggview",postid); } public virtual string OpmlStyleSheet() { return urlData.FormatUrl("opmlxsl"); } public virtual string RssStyleSheet() { return urlData.FormatUrl("rssxsl"); } public virtual string RssImageDisabled() { return urlData.FormatUrl("secureRssImageDisabled"); } public virtual string RssImage(bool isSecure) { if(isSecure) return urlData.FormatUrl("secureRssImage"); else return urlData.FormatUrl("rssImage"); } public virtual string FeedIcon() { return urlData.FormatUrl("feedIcon"); } #endregion #region Atom public virtual string AtomStyleSheet() { return urlData.FormatUrl("atomxsl"); } #endregion #region NNTP public virtual string NntpImage { get { return urlData.FormatUrl("nntpImage"); } } #endregion #region Email public virtual string EmailImage { get { return urlData.FormatUrl("emailImage"); } } #endregion #region Search public virtual string Search { get { return urlData.FormatUrl("search"); } } public virtual string SearchAdvanced { get { return urlData.FormatUrl("search_Advanced"); } } public virtual string EmptySearchAdvanced { get { return urlData.FormatUrl("search_ForTextEmpty"); } } public virtual string SearchRss(string searchQueryString) { return urlData.FormatUrl("search_rss", searchQueryString); } /// /// Search for text url (short querystring) /// public virtual string SearchForText(string searchQueryString) { return urlData.FormatUrl("search_ForText", searchQueryString); } public virtual string SearchByUser (int userID) { SearchQuery query = new SearchQuery(); query.UsersToSearch = new int[] { userID }; query.SortBy = SearchSort.DateDescending; return SearchForText(SearchProvider.Instance().SearchQueryString(query)); } /// /// Search by user id & application type /// /// User ID /// Application Type /// public virtual string SearchByUser (int userID, ApplicationType applicationType) { SearchQuery query = new SearchQuery(); query.UsersToSearch = new int[] { userID }; query.ApplicationTypes = new ApplicationType[] {applicationType}; query.SortBy = SearchSort.DateDescending; return SearchForText(SearchProvider.Instance().SearchQueryString(query)); } // public virtual string SearchForUser (string username) // { // return urlData.FormatUrl("search_ForUser", username); // } // public virtual string SearchForUserAdmin (string username) // { // return urlData.FormatUrl("search_ForUserAdmin", username); // } // public virtual string GallerySearchForText(string textToSearchFor, string forumsToSearch) // { // return urlData.FormatUrl("gallery_Search", textToSearchFor, forumsToSearch); // } #endregion #region FAQ public virtual string FAQ { get { return urlData.FormatUrl("faq", CSContext.Current.User.Profile.Language); } } #endregion #region Login, Logout, Messages public virtual string LoginReturnHome { get { return urlData.FormatUrl("login", Globals.ApplicationPath); } } public virtual string Login { get { string currentPath = CSContext.Current.Context.Request.Url.PathAndQuery; string returnUrl = null; returnUrl = ExtractQueryParams(currentPath)["ReturnUrl"]; if (Globals.IsNullorEmpty(returnUrl)) returnUrl = CSContext.Current.RawUrl; returnUrl = Globals.UrlEncode(returnUrl); return urlData.FormatUrl("login", returnUrl); } } public virtual string LoginWithInvitation(Guid invitationKey) { return urlData.FormatUrl("login_WithInvitation", invitationKey.ToString()); } public virtual string Logout { get { return urlData.FormatUrl("logout"); } } public virtual string Message (CSExceptionType exceptionType) { return urlData.FormatUrl("message", ((int) exceptionType).ToString()); } public virtual string Message (CSExceptionType exceptionType, string returnUrl) { return urlData.FormatUrl("message_return", ((int) exceptionType).ToString(), returnUrl); } public virtual string ModalMessage (CSExceptionType exceptionType) { return urlData.FormatUrl("message_modal", ((int) exceptionType).ToString()); } public virtual string ModalMessage (CSExceptionType exceptionType, string returnUrl) { return urlData.FormatUrl("message_modal_return", ((int) exceptionType).ToString(), returnUrl); } #endregion public static string FormatUrlWithUserNameToken(string url, User user, bool appendToExistingQueryString) { return string.Format("{0}{1}UserName={2}&Token={3}",url,appendToExistingQueryString ? "&" : "?",Globals.UrlEncode(user.Username),user.PublicToken); } public virtual string Redirect(string url) { return urlData.FormatUrl("redirect",Globals.UrlEncode(url)); } public virtual string Home { get { return urlData.FormatUrl("home"); } } #region Forum / ForumGroup public virtual string ForumsHome { get { return urlData.FormatUrl("forumshome"); } } public virtual string ForumPersonalize { get { return urlData.FormatUrl("forumPersonalize"); } } public virtual string ForumGroup (int forumGroupID) { return urlData.FormatUrl("forumGroup", forumGroupID.ToString()); } #endregion public virtual string WeblogsHome { get { return urlData.FormatUrl("webloghome"); } } public virtual string GalleriesHome { get { return urlData.FormatUrl("galleryhome"); } } #region Private static helper methods public static string RemoveParameters (string url) { if (url == null) return string.Empty; int paramStart = url.IndexOf("?"); if (paramStart > 0) return url.Substring(0, paramStart); return url; } protected static NameValueCollection ExtractQueryParams(string url) { int startIndex = url.IndexOf("?"); NameValueCollection values = new NameValueCollection(); if (startIndex <= 0) return values; string[] nameValues = url.Substring(startIndex + 1).Split('&'); foreach (string s in nameValues) { string[] pair = s.Split('='); string name = pair[0]; string value = string.Empty; if (pair.Length > 1) value = pair[1]; values.Add(name, value); } return values; } public static string FormatUrlWithParameters(string url, string parameters) { if (url == null) return string.Empty; if (parameters.Length > 0) url = url + "?" + parameters; return url; } #endregion #region Public helper methods // private static Regex ReWriteFilter = null; // // public static bool RewriteUrl(string path, string queryString, out string newPath) // { // // //ReWriterFilter enables us to mark sections of the SiteUrls.config as non rewritable. This is particularly helpful // //when moving the weblogs and gallery to the root of the site. Otherwise, there is a very likely chance /user /admin /utility // // /search will be mistaken treated as a blog or gallery. // if(ReWriteFilter == null) // ReWriteFilter = new Regex(SiteUrls.Instance().LocationFilter, RegexOptions.IgnoreCase|RegexOptions.Compiled); // // //If we do not match a filter, continue one // if(!ReWriteFilter.IsMatch(path)) // { // //now, we walk through all of our ReWritable Urls and see if any match // ArrayList urls = SiteUrls.Instance().ReWrittenUrls; // if(urls.Count > 0) // { // foreach(ReWrittenUrl url in urls) // { // if(url.IsMatch(path)) // { // newPath = url.Convert(path,queryString); // return true; // } // // } // } // } // // //Nothing found // newPath = null; // return false; // } public struct ForumLocation { public string Description; public string UrlName; public int ForumID; public int ForumGroupID; public int PostID; public int UserID; } public static ForumLocation GetForumLocation (string encodedLocation) { // Decode the location ForumLocation location = new ForumLocation(); string[] s = encodedLocation.Split(':'); try { location.UrlName = s[0]; location.ForumGroupID = int.Parse(s[1]); location.ForumID = int.Parse(s[2]); location.PostID = int.Parse(s[3]); location.UserID = int.Parse(s[4]); } catch {} return location; } private static string CleanupUrlPath (string urlPath) { string outUrlPath = urlPath; /* CSContext csContext = CSContext.Current; NameValueCollection locations = Globals.GetSiteUrls().Locations; switch (csContext.ApplicationType) { case ApplicationType.Admin: outUrlPath = outUrlPath.Replace( locations["admin"].ToLower(), "" ); break; case ApplicationType.Forum: outUrlPath = outUrlPath.Replace( locations["forums"].ToLower(), "" ); break; case ApplicationType.Gallery: outUrlPath = outUrlPath.Replace( locations["galleries"].ToLower(), "" ); break; case ApplicationType.Weblog: outUrlPath = outUrlPath.Replace( locations["weblogs"].ToLower(), "" ); break; default: outUrlPath = outPath.Replace( Globals.ApplicationPath.ToLower(), "" ); if (outUrlPath.IndexOf( "/", 0 ) == 0) outUrlPath = outUrlPath.Substring( 1, (outUrlPath.Length - 1) ); break; } */ // Remove ReturnUrl param if found // int idx = outUrlPath.IndexOf( "?returnurl=", 0 ); if (idx > 0) { outUrlPath = outUrlPath.Remove( idx, (outUrlPath.Length - idx) ); } return outUrlPath; } #region LocationKey // Takes a URL used in the forums and performs a reverse // lookup to return a friendly name of the currently viewed // resource // // public static string LocationKey () // { // CSContext csContext = CSContext.Current; // string url = csContext.RawUrl.ToLower(); // // if (Globals.ApplicationPath.Length > 0) // url = url.Replace( Globals.ApplicationPath.ToLower(), "" ); // // // Clean up the url applying various filters // // // url = CleanupUrlPath( url ); // // NameValueCollection reversePaths = Globals.GetSiteUrls().ReversePaths; // int forumGroupIDqs = -1; // int forumIDqs = -1; // int postIDqs = -1; // int userIDqs = -1; // int modeIDqs = -1; // // // Modify the url so we can perform a reverse lookup // // // try // { // for (int i = 0; i < csContext.Context.Request.QueryString.Count; i++) // { // string key = csContext.Context.Request.QueryString.Keys[i].ToLower(); // // switch (key) // { // case "forumid": // forumIDqs = int.Parse(csContext.Context.Request.QueryString[key]); // break; // case "postid": // postIDqs = int.Parse(csContext.Context.Request.QueryString[key]); // break; // case "userid": // userIDqs = int.Parse(csContext.Context.Request.QueryString[key]); // break; // case "forumgroupid": // forumGroupIDqs = int.Parse(csContext.Context.Request.QueryString[key]); // break; // case "mode": // modeIDqs = int.Parse(csContext.Context.Request.QueryString[key]); // break; // } // url = url.Replace(csContext.Context.Request.QueryString[key], "{"+i+"}"); // } // // } // catch // { // return ""; // } // // string retval = reversePaths[url]; // // if ((retval == null) || (retval == string.Empty)) // retval = "/"; // // return retval + ":" + forumGroupIDqs + ":" + forumIDqs + ":" + postIDqs + ":" + userIDqs + ":" + modeIDqs; // // // } #endregion #endregion #region Public properties public ArrayList MainNavigationLinks { get { return urlData.TabUrls; } } public virtual string LocationFilter { get { return urlData.LocationFilter; } } public SiteUrlsData UrlData { get{return urlData;} } public NameValueCollection ReversePaths { get { return urlData.ReversePaths; } } public LocationSet Locations { get { return urlData.LocationSet; } } public LocationSet LocationSet { get { return urlData.LocationSet; } } #endregion } }