using Oqtane.Models; using System; using System.Collections.Generic; using System.Globalization; using System.IO; using System.Linq; using System.Text; using System.Text.RegularExpressions; using File = Oqtane.Models.File; namespace Oqtane.Shared { public static class Utilities { public static string ToModuleDefinitionName(this Type type) { if (type == null) return null; var assemblyFullName = type.Assembly.FullName; var assemblyName = assemblyFullName.Substring(0, assemblyFullName.IndexOf(",", StringComparison.Ordinal)); return $"{type.Namespace}, {assemblyName}"; } public static (string UrlParameters, string Querystring, string Anchor) ParseParameters(string parameters) { // /urlparameters /urlparameters?Id=1 /urlparameters#5 /urlparameters?Id=1#5 /urlparameters?reload#5 // Id=1 Id=1#5 reload#5 reload // #5 var urlparameters = string.Empty; var querystring = string.Empty; var anchor = string.Empty; if (parameters.Contains('#')) { anchor = parameters.Split('#').Last(); parameters = parameters.Replace("#" + anchor, ""); } if (parameters.Contains('?')) { urlparameters = parameters.Split('?').First(); querystring = parameters.Replace(urlparameters + "?", ""); } else if (parameters.Contains('/')) { urlparameters = parameters; } else { querystring = parameters; } return (urlparameters, querystring, anchor); } public static string NavigateUrl(string alias, string path, string parameters) { string urlparameters; string querystring; string anchor; // parse parameters (urlparameters, querystring, anchor) = ParseParameters(parameters); if (!string.IsNullOrEmpty(urlparameters)) { if (urlparameters.StartsWith("/")) urlparameters = urlparameters.Remove(0, 1); path += $"/{Constants.UrlParametersDelimiter}/{urlparameters}"; } // build url var uriBuilder = new UriBuilder { Path = !string.IsNullOrEmpty(alias) ? (!string.IsNullOrEmpty(path)) ? $"{alias}/{path}" : $"{alias}" : $"{path}", Query = querystring, }; anchor = string.IsNullOrEmpty(anchor) ? "" : "#" + anchor; return uriBuilder.Uri.PathAndQuery + anchor; } public static string EditUrl(string alias, string path, int moduleid, string action, string parameters) { if (moduleid != -1) { path += $"/{Constants.ModuleDelimiter}/{moduleid}"; if (!string.IsNullOrEmpty(action)) { path += $"/{action}"; } } return NavigateUrl(alias, path, parameters); } public static string ContentUrl(Alias alias, int fileId) { return ContentUrl(alias, fileId, false); } public static string ContentUrl(Alias alias, int fileId, bool asAttachment) { var aliasUrl = (alias != null && !string.IsNullOrEmpty(alias.Path)) ? "/" + alias.Path : ""; var method = asAttachment ? "/attach" : ""; return $"{aliasUrl}{Constants.ContentUrl}{fileId}{method}"; } public static string ImageUrl(Alias alias, int fileId, int width, int height, string mode) { return ImageUrl(alias, fileId, width, height, mode, "", "", 0, false); } public static string ImageUrl(Alias alias, int fileId, int width, int height, string mode, string position, string background, int rotate, bool recreate) { var aliasUrl = (alias != null && !string.IsNullOrEmpty(alias.Path)) ? "/" + alias.Path : ""; mode = string.IsNullOrEmpty(mode) ? "crop" : mode; position = string.IsNullOrEmpty(position) ? "center" : position; background = string.IsNullOrEmpty(background) ? "000000" : background; return $"{aliasUrl}{Constants.ImageUrl}{fileId}/{width}/{height}/{mode}/{position}/{background}/{rotate}/{recreate}"; } public static string TenantUrl(Alias alias, string url) { url = (!url.StartsWith("/")) ? "/" + url : url; return (alias != null && !string.IsNullOrEmpty(alias.Path)) ? "/" + alias.Path + url : url; } public static string FormatContent(string content, Alias alias, string operation) { switch (operation) { case "save": content = content.Replace(UrlCombine("Content", "Tenants", alias.TenantId.ToString(), "Sites", alias.SiteId.ToString()), "[siteroot]"); content = content.Replace(alias.Path + Constants.ContentUrl, Constants.ContentUrl); break; case "render": content = content.Replace("[siteroot]", UrlCombine("Content", "Tenants", alias.TenantId.ToString(), "Sites", alias.SiteId.ToString())); content = content.Replace(Constants.ContentUrl, alias.Path + Constants.ContentUrl); break; } return content; } public static string GetTypeName(string fullyqualifiedtypename) { if (fullyqualifiedtypename.Contains(",")) { return fullyqualifiedtypename.Substring(0, fullyqualifiedtypename.IndexOf(",")); } else { return fullyqualifiedtypename; } } public static string GetFullTypeName(string fullyqualifiedtypename) { if (fullyqualifiedtypename.Contains(", Version=")) { return fullyqualifiedtypename.Substring(0, fullyqualifiedtypename.IndexOf(", Version=")); } else { return fullyqualifiedtypename; } } public static string GetAssemblyName(string fullyqualifiedtypename) { fullyqualifiedtypename = GetFullTypeName(fullyqualifiedtypename); if (fullyqualifiedtypename.Contains(",")) { return fullyqualifiedtypename.Substring(fullyqualifiedtypename.IndexOf(",") + 1).Trim(); } else { return ""; } } public static string GetTypeNameLastSegment(string typename, int segment) { if (typename.Contains(",")) { // remove assembly if fully qualified type typename = typename.Substring(0, typename.IndexOf(",")); } // segment 0 is the last segment, segment 1 is the second to last segment, etc... string[] segments = typename.Split('.'); string name = ""; if (segment < segments.Length) { name = segments[segments.Length - (segment + 1)]; } return name; } public static string GetFriendlyUrl(string text) { string result = ""; if (text != null) { var normalizedString = text.ToLowerInvariant().Normalize(NormalizationForm.FormD); var stringBuilder = new StringBuilder(); var stringLength = normalizedString.Length; var prevdash = false; char c; for (int i = 0; i < stringLength; i++) { c = normalizedString[i]; switch (CharUnicodeInfo.GetUnicodeCategory(c)) { case UnicodeCategory.LowercaseLetter: case UnicodeCategory.UppercaseLetter: case UnicodeCategory.DecimalDigitNumber: if (c < 128) stringBuilder.Append(c); else stringBuilder.Append(RemapInternationalCharToAscii(c)); prevdash = false; break; case UnicodeCategory.SpaceSeparator: case UnicodeCategory.ConnectorPunctuation: case UnicodeCategory.DashPunctuation: case UnicodeCategory.OtherPunctuation: case UnicodeCategory.MathSymbol: if (!prevdash) { stringBuilder.Append('-'); prevdash = true; } break; } } result = stringBuilder.ToString().Trim('-'); } return result; } private static string RemapInternationalCharToAscii(char c) { string s = c.ToString().ToLowerInvariant(); if ("àåáâäãåą".Contains(s)) { return "a"; } else if ("èéêëę".Contains(s)) { return "e"; } else if ("ìíîïı".Contains(s)) { return "i"; } else if ("òóôõöøőð".Contains(s)) { return "o"; } else if ("ùúûüŭů".Contains(s)) { return "u"; } else if ("çćčĉ".Contains(s)) { return "c"; } else if ("żźž".Contains(s)) { return "z"; } else if ("śşšŝ".Contains(s)) { return "s"; } else if ("ñń".Contains(s)) { return "n"; } else if ("ýÿ".Contains(s)) { return "y"; } else if ("ğĝ".Contains(s)) { return "g"; } else if (c == 'ř') { return "r"; } else if (c == 'ł') { return "l"; } else if (c == 'đ') { return "d"; } else if (c == 'ß') { return "ss"; } else if (c == 'þ') { return "th"; } else if (c == 'ĥ') { return "h"; } else if (c == 'ĵ') { return "j"; } else { return ""; } } public static bool IsValidEmail(string email) { if (string.IsNullOrEmpty(email)) return false; return Regex.IsMatch(email, @"^(?("")("".+?(? ParseQueryString(string query) { Dictionary dictionary = new Dictionary(); if (!string.IsNullOrEmpty(query)) { query = query.Substring(1); string str = query; char[] separator = new char[1] { '&' }; foreach (string key in str.Split(separator, StringSplitOptions.RemoveEmptyEntries)) { if (key != "") { if (key.Contains("=")) { string[] strArray = key.Split('=', StringSplitOptions.None); dictionary.Add(strArray[0], strArray[1]); } else dictionary.Add(key, "true"); } } } return dictionary; } public static string LogMessage(object @class, string message) { return $"[{@class.GetType()}] {message}"; } } }