using System; using System.Globalization; using System.IO; using System.Net; using System.Net.Mail; using System.Text; using System.Text.RegularExpressions; using System.Web; using System.Web.UI; using System.Xml; using System.Xml.XPath; using umbraco.BusinessLogic; using umbraco.cms.businesslogic; using umbraco.cms.businesslogic.media; using umbraco.cms.businesslogic.member; using umbraco.cms.businesslogic.propertytype; using umbraco.cms.businesslogic.relation; using umbraco.cms.businesslogic.web; using umbraco.cms.helpers; using umbraco.presentation.cache; using umbraco.scripting; using umbraco.DataLayer; using System.Web.Security; using umbraco.cms.businesslogic.language; using umbraco.IO; using umbraco.presentation; using System.Collections; using System.Collections.Generic; namespace umbraco { /// /// Function library for umbraco. Includes various helper-methods and methods to /// save and load data from umbraco. /// /// Especially usefull in XSLT where any of these methods can be accesed using the umbraco.library name-space. Example: /// <xsl:value-of select="umbraco.library:NiceUrl(@id)"/> /// public class library { #region Declarations /// /// Used by umbraco's publishing enginge, to determine if publishing is currently active /// public static bool IsPublishing = false; /// /// Used by umbraco's publishing enginge, to how many nodes is publish in the current publishing cycle /// public static int NodesPublished = 0; /// /// Used by umbraco's publishing enginge, to determine the start time of the current publishing cycle. /// public static DateTime PublishStart; private page _page; #endregion #region Properties protected static ISqlHelper SqlHelper { get { return umbraco.BusinessLogic.Application.SqlHelper; } } #endregion #region Constructors /// /// Empty constructor /// public library() { } public library(int id) { _page = new page(((System.Xml.IHasXmlNode)GetXmlNodeById(id.ToString()).Current).GetNode()); } /// /// Initializes a new instance of the class. /// /// The page. public library(page page) { _page = page; } #endregion #region Python Helper functions /// /// Executes the given python script and returns the standardoutput. /// The Globals known from python macros are not accessible in this context. /// Neither macro or page nor the globals known from python macros are /// accessible in this context. Only stuff we initialized in site.py /// can be used. /// /// The filename of the python script including the extension .py /// Returns the StandardOutput public static string PythonExecuteFile(string file) { try { string path = IOHelper.MapPath(SystemDirectories.Python + "/" + file); object res = python.executeFile(path); return res.ToString(); } catch (Exception e) { return e.Message; } } /// /// Executes the given python expression and returns the standardoutput. /// The Globals known from python macros are not accessible in this context. /// Neighter macro or page nor the globals known from python macros are /// accessible in this context. Only stuff we initialized in site.py /// can be used. /// /// Python expression to execute /// Returns the StandardOutput public static string PythonExecute(string expression) { try { object res = python.execute(expression); return res.ToString(); } catch (Exception e) { return e.Message; } } #endregion #region Publish Helper Methods // Esben Carlsen: Commented out, not referenced anywhere ///// ///// Updates nodes and eventually subnodes, making the latest version the one to be published. ///// Should always be used with library.rePublishNodes(), to ensure that the xml source is ///// updated ///// ///// Publish childnodes as well ///// //public static void PublishDocument(Guid nodeID, bool publishChildren, User u) //{ // Document d = new Document(nodeID, true); // d.Publish(u); // NodesPublished++; // if(publishChildren) // foreach(Document dc in d.Children) // { // PublishDocument(dc.UniqueId, true, u); // } //} /// /// Unpublish a node, by removing it from the runtime xml index. Note, prior to this the Document should be /// marked unpublished by setting the publish property on the document object to false /// /// The Id of the Document to be unpublished public static void UnPublishSingleNode(int DocumentId) { //PPH Added dispatcher support if (UmbracoSettings.UseDistributedCalls) dispatcher.Remove( new Guid("27ab3022-3dfa-47b6-9119-5945bc88fd66"), DocumentId); else content.Instance.ClearDocumentCache(DocumentId); } /// /// Publishes a Document by adding it to the runtime xml index. Note, prior to this the Document should be /// marked published by calling Publish(User u) on the document object. /// /// The Id of the Document to be published public static void UpdateDocumentCache(int DocumentId) { if (UmbracoSettings.UseDistributedCalls) dispatcher.Refresh( new Guid("27ab3022-3dfa-47b6-9119-5945bc88fd66"), DocumentId); else content.Instance.UpdateDocumentCache(DocumentId); } /// /// Publishes the single node, this method is obsolete /// /// The document id. [Obsolete("Please use: umbraco.library.UpdateDocumentCache")] public static void PublishSingleNode(int DocumentId) { UpdateDocumentCache(DocumentId); } /// /// Refreshes the xml cache for all nodes /// public static void RefreshContent() { if (UmbracoSettings.UseDistributedCalls) { dispatcher.RefreshAll(new Guid("27ab3022-3dfa-47b6-9119-5945bc88fd66")); } else { content.Instance.RefreshContentFromDatabaseAsync(); } } /// /// Re-publishes all nodes under a given node /// /// The ID of the node and childnodes that should be republished [Obsolete("Please use: umbraco.library.RefreshContent")] public static string RePublishNodes(int nodeID) { //PPH - added dispatcher support to this call.. if (UmbracoSettings.UseDistributedCalls) dispatcher.RefreshAll(new Guid("27ab3022-3dfa-47b6-9119-5945bc88fd66")); else { content.Instance.RefreshContentFromDatabaseAsync(); } return string.Empty; } /// /// Re-publishes all nodes under a given node /// /// The ID of the node and childnodes that should be republished [Obsolete("Please use: umbraco.library.RefreshContent")] public static void RePublishNodesDotNet(int nodeID) { content.Instance.RefreshContentFromDatabaseAsync(); } //private static Hashtable parents = new Hashtable(); //private static Hashtable nodes = new Hashtable(); //private static int nodeRepublishCounter = 0; //public static void RePublishNodesDotNet(int nodeID) //{ // RePublishNodesDotNet(nodeID, true); //} // Esben Carlsen: Commented out, is not referenced anywhere //public static void _RePublishNodesDotNet(int nodeID, bool SaveToDisk) //{ // content.isInitializing = true; // content.Instance.XmlContent = null; // BusinessLogic.Log.Add(BusinessLogic.LogTypes.Debug, BusinessLogic.User.GetUser(0), -1, "Republishing starting"); // cms.businesslogic.cache.Cache.ClearAllCache(); // XmlDocument xmlDoc = new XmlDocument(); // // Create id -1 attribute // xmlDoc.LoadXml(""); // XmlNode n = xmlDoc.DocumentElement; // buildNodes(ref xmlDoc, ref n, -1); // content.Instance.XmlContent.Load(n.OuterXml); // // reload xml // n = null; // xmlDoc = null; // if (SaveToDisk) // content.SaveCacheToDisk(false); // // Reload content // requestHandler.ClearProcessedRequests(); // content.clearContentCache(); // BusinessLogic.Log.Add(BusinessLogic.LogTypes.Debug, BusinessLogic.User.GetUser(0), -1, "Republishing done"); // content.isInitializing = false; //} // private static void buildNodes(ref XmlDocument Xd, ref XmlNode CurrentElement, int ParentId) // { // string sql = // @"select umbracoNode.id, umbracoNode.sortOrder, cmsContentXml.xml from umbracoNode // inner join cmsContentXml on cmsContentXml.nodeId = umbracoNode.id and umbracoNode.nodeObjectType = 'C66BA18E-EAF3-4CFF-8A22-41B16D66A972' // and umbracoNode.parentId = @parentId // order by umbracoNode.sortOrder"; // IRecordsReader dr = // SqlHelper.ExecuteReader(sql, SqlHelper.CreateParameter("@parentId", ParentId)); // while(dr.Read()) // { // int currentId = int.Parse(dr["id"].ToString()); // XmlNode n = xmlHelper.ImportXmlNodeFromText(dr["xml"].ToString(), ref Xd); // CurrentElement.AppendChild(n); // buildNodes(ref Xd, ref n, currentId); // } // dr.Close(); // } /// /// Refreshes the runtime xml index. /// Note: This *doesn't* mark any non-published document objects as published /// /// Always use -1 /// Not used [Obsolete("Please use: content.Instance.RefreshContentFromDatabaseAsync")] public static void RePublishNodesDotNet(int nodeID, bool SaveToDisk) { content.Instance.RefreshContentFromDatabaseAsync(); } #endregion #region Xslt Helper functions /// /// Add a session variable to the current user /// /// The Key of the variable /// The Value public static void setSession(string key, string value) { if (HttpContext.Current.Session != null) HttpContext.Current.Session[key] = value; } /// /// Add a cookie variable to the current user /// /// The Key of the variable /// The Value of the variable public static void setCookie(string key, string value) { StateHelper.SetCookieValue(key, value); } /// /// Returns a string with a friendly url from a node. /// IE.: Instead of having /482 (id) as an url, you can have /// /screenshots/developer/macros (spoken url) /// /// Identifier for the node that should be returned /// String with a friendly url from a node public static string NiceUrl(int nodeID) { try { int startNode = 1; if (GlobalSettings.HideTopLevelNodeFromPath) startNode = 2; return niceUrlDo(nodeID, startNode); } catch { return "#"; } } /// /// This method will always add the root node to the path. You should always use NiceUrl, as that is the /// only one who checks for toplevel node settings in the web.config /// /// Identifier for the node that should be returned /// String with a friendly url from a node public static string NiceUrlFullPath(int nodeID) { return niceUrlDo(nodeID, 1); } public static string ResolveVirtualPath(string path) { return IOHelper.ResolveUrl(path); } private static string niceUrlDo(int nodeID, int startNodeDepth) { bool directoryUrls = GlobalSettings.UseDirectoryUrls; string baseUrl = SystemDirectories.Root; // SystemDirectories.Umbraco; //baseUrl = baseUrl.Substring(0, baseUrl.LastIndexOf("/")); bool atDomain = false; string currentDomain = HttpContext.Current.Request.ServerVariables["SERVER_NAME"].ToLower(); if (UmbracoSettings.UseDomainPrefixes && Domain.Exists(currentDomain)) atDomain = true; // Find path from nodeID String tempUrl = ""; XmlElement node = UmbracoContext.Current.GetXml().GetElementById(nodeID.ToString()); String[] splitpath = null; if (node != null) { try { splitpath = node.Attributes.GetNamedItem("path").Value.ToString(). Split(",".ToCharArray()); int startNode = startNodeDepth; // check root nodes for domains if (UmbracoSettings.UseDomainPrefixes && startNode > 1) { if (node.ParentNode.Name.ToLower() == "node") { Domain[] domains = Domain.GetDomainsById(int.Parse(node.ParentNode.Attributes.GetNamedItem("id").Value)); if ( domains.Length > 0) { tempUrl = getUrlByDomain(int.Parse(node.ParentNode.Attributes.GetNamedItem("id").Value), "", atDomain, currentDomain, true); } // test for domains on root nodes, then make the url domain only } else if (Domain.GetDomainsById(nodeID).Length > 0) { tempUrl = getUrlByDomain(nodeID, "", false, currentDomain, false); return tempUrl; } } if (splitpath.Length > startNode) { for (int i = startNode; i < splitpath.Length; i++) { tempUrl = getUrlByDomain(int.Parse(splitpath[i]), tempUrl, atDomain, currentDomain, false); } } else { // check the root node for language tempUrl += getUrlByDomain(nodeID, "", atDomain, currentDomain, false); } } catch (Exception e) { HttpContext.Current.Trace.Warn("library.NiceUrl", string.Format("Error generating nice url for id '{0}'", nodeID), e); tempUrl = "/" + nodeID; } tempUrl = appendUrlExtension(baseUrl, directoryUrls, tempUrl); } else HttpContext.Current.Trace.Warn("niceurl", string.Format("No node found at '{0}'", nodeID)); return tempUrl; } private static string appendUrlExtension(string baseUrl, bool directoryUrls, string tempUrl) { if (!directoryUrls) // append .aspx extension if the url includes other than just the domain name if (tempUrl.ToString() != "" && (!tempUrl.StartsWith("http://") || tempUrl.Replace("http://", "").IndexOf("/") > -1)) tempUrl = baseUrl + tempUrl + ".aspx"; return tempUrl; } private static string getUrlByDomain(int DocumentId, string tempUrl, bool atDomain, string currentDomain, bool emptyOnSameDomain) { Domain[] domains = Domain.GetDomainsById(DocumentId); if (!UmbracoSettings.UseDomainPrefixes || domains.Length == 0) tempUrl += "/" + url.FormatUrl( UmbracoContext.Current.GetXml().GetElementById(DocumentId.ToString()).Attributes.GetNamedItem ("urlName").Value); else { // check if one of the domains are the same as the current one if (atDomain) { bool inDomainRange = false; foreach (Domain d in domains) if (d.Name.ToLower() == currentDomain) { inDomainRange = true; break; } if (inDomainRange) { if (emptyOnSameDomain) return tempUrl; else tempUrl = "/" + url.FormatUrl( UmbracoContext.Current.GetXml().GetElementById(DocumentId.ToString()).Attributes. GetNamedItem("urlName").Value); } else tempUrl = "http://" + domains[0].Name; } else tempUrl = "http://" + domains[0].Name; } return tempUrl; } /// /// Returns a string with the data from the given element of a node. Both elements (data-fields) /// and properties can be used - ie: /// getItem(1, nodeName) will return a string with the name of the node with id=1 even though /// nodeName is a property and not an element (data-field). /// /// Identifier for the node that should be returned /// The element that should be returned /// Returns a string with the data from the given element of a node public static string GetItem(int nodeID, String alias) { XmlDocument umbracoXML = UmbracoContext.Current.GetXml(); if (umbracoXML.GetElementById(nodeID.ToString()) != null) if ( ",id,version,parentID,level,writerID,editDataType,template,sortOrder,createDate,updateDate,nodeName,writerName,path," . IndexOf("," + alias + ",") > -1) return umbracoXML.GetElementById(nodeID.ToString()).Attributes.GetNamedItem(alias).Value; else if ( umbracoXML.GetElementById(nodeID.ToString()).SelectSingleNode("./data [@alias='" + alias + "']") != null) return umbracoXML.GetElementById(nodeID.ToString()).SelectSingleNode("./data [@alias = '" + alias + "']").ChildNodes[0]. Value; //.Value + "*"; else return string.Empty; else return string.Empty; } /// /// Checks with the Assigned domains settings and retuns an array the the Domains matching the node /// /// Identifier for the node that should be returned /// A Domain array with all the Domains that matches the nodeId public static Domain[] GetCurrentDomains(int NodeId) { string[] pathIds = GetItem(NodeId, "path").Split(','); for (int i = pathIds.Length - 1; i > 0; i--) { Domain[] retVal = Domain.GetDomainsById(int.Parse(pathIds[i])); if (retVal.Length > 0) { return retVal; } } return null; } /// /// Returns a string with the data from the given element of the current node. Both elements (data-fields) /// and properties can be used - ie: /// getItem(nodeName) will return a string with the name of the current node/page even though /// nodeName is a property and not an element (data-field). /// /// /// public static string GetItem(String alias) { try { int currentID = int.Parse(HttpContext.Current.Items["pageID"].ToString()); return GetItem(currentID, alias); } catch (Exception ItemException) { HttpContext.Current.Trace.Warn("library.GetItem", "Error reading '" + alias + "'", ItemException); return string.Empty; } } /// /// Returns that name of a generic property /// /// The Alias of the content type (ie. Document Type, Member Type or Media Type) /// The Alias of the Generic property (ie. bodyText or umbracoNaviHide) /// A string with the name. If nothing matches the alias, an empty string is returned public static string GetPropertyTypeName(string ContentTypeAlias, string PropertyTypeAlias) { try { umbraco.cms.businesslogic.ContentType ct = umbraco.cms.businesslogic.ContentType.GetByAlias(ContentTypeAlias); PropertyType pt = ct.getPropertyType(PropertyTypeAlias); return pt.Name; } catch { return string.Empty; } } /// /// Returns the Member Name from an umbraco member object /// /// The identifier of the Member /// The Member name matching the MemberId, an empty string is member isn't found public static string GetMemberName(int MemberId) { if (MemberId != 0) { try { Member m = new Member(MemberId); return m.Text; } catch { return string.Empty; } } else return string.Empty; } /// /// Get a media object as an xml object /// /// The identifier of the media object to be returned /// If true, children of the media object is returned /// An umbraco xml node of the media (same format as a document node) public static XPathNodeIterator GetMedia(int MediaId, bool Deep) { try { Media m = new Media(MediaId); if (m.nodeObjectType == Media._objectType) { XmlDocument mXml = new XmlDocument(); mXml.LoadXml(m.ToXml(mXml, Deep).OuterXml); XPathNavigator xp = mXml.CreateNavigator(); return xp.Select("/node"); } } catch { } XmlDocument xd = new XmlDocument(); xd.LoadXml(string.Format("No media is maching '{0}'", MediaId)); return xd.CreateNavigator().Select("/"); } /// /// Get a member as an xml object /// /// The identifier of the member object to be returned /// An umbraco xml node of the member (same format as a document node), but with two additional attributes on the "node" element: /// "email" and "loginName". /// public static XPathNodeIterator GetMember(int MemberId) { try { Member m = new Member(MemberId); XmlDocument mXml = new XmlDocument(); mXml.LoadXml(m.ToXml(mXml, false).OuterXml); XPathNavigator xp = mXml.CreateNavigator(); return xp.Select("/node"); } catch { } XmlDocument xd = new XmlDocument(); xd.LoadXml(string.Format("No member is maching '{0}'", MemberId)); return xd.CreateNavigator().Select("/"); } /// /// Get the current member as an xml node /// /// Look in documentation for umbraco.library.GetMember(MemberId) for more information public static XPathNodeIterator GetCurrentMember() { Member m = Member.GetCurrentMember(); if (m != null) { XmlDocument mXml = new XmlDocument(); mXml.LoadXml(m.ToXml(mXml, false).OuterXml); XPathNavigator xp = mXml.CreateNavigator(); return xp.Select("/node"); } XmlDocument xd = new XmlDocument(); xd.LoadXml( "No current member exists (best practice is to validate with 'isloggedon()' prior to this call)"); return xd.CreateNavigator().Select("/"); } /// /// Whether or not the current user is logged in (as a member) /// /// True is the current user is logged in public static bool IsLoggedOn() { /* MembershipUser u = Membership.GetUser(); return u != null; */ return Member.IsLoggedOn(); } public static XPathNodeIterator AllowedGroups(int documentId, string path) { XmlDocument xd = new XmlDocument(); xd.LoadXml(""); foreach (string role in Access.GetAccessingMembershipRoles(documentId, path)) xd.DocumentElement.AppendChild(xmlHelper.addTextNode(xd, "role", role)); return xd.CreateNavigator().Select("."); } /// /// Check if a document object is protected by the "Protect Pages" functionality in umbraco /// /// The identifier of the document object to check /// The full path of the document object to check /// True if the document object is protected public static bool IsProtected(int DocumentId, string Path) { return Access.IsProtected(DocumentId, Path); } /// /// Check if the current user has access to a document /// /// The identifier of the document object to check /// The full path of the document object to check /// True if the current user has access or if the current document isn't protected public static bool HasAccess(int NodeId, string Path) { if (IsProtected(NodeId, Path)) { if (Member.IsLoggedOn()) return Access.HasAccess(NodeId, Path, Membership.GetUser()); else return false; } else return true; } /// /// Encrypts the string using md5 /// /// The text. /// Md5 encrupted string public static string md5(string text) { System.Security.Cryptography.MD5CryptoServiceProvider x = new System.Security.Cryptography.MD5CryptoServiceProvider(); byte[] bs = System.Text.Encoding.UTF8.GetBytes(text); bs = x.ComputeHash(bs); System.Text.StringBuilder s = new System.Text.StringBuilder(); foreach (byte b in bs) { s.Append(b.ToString("x2").ToLower()); } return s.ToString(); } /// /// Compare two dates /// /// The first date to compare /// The second date to compare /// True if the first date is greater than the second date public static bool DateGreaterThan(string firstDate, string secondDate) { if (DateTime.Parse(firstDate) > DateTime.Parse(secondDate)) return true; else return false; } /// /// Compare two dates /// /// The first date to compare /// The second date to compare /// True if the first date is greater than or equal the second date public static bool DateGreaterThanOrEqual(string firstDate, string secondDate) { if (DateTime.Parse(firstDate) >= DateTime.Parse(secondDate)) return true; else return false; } /// /// Check if a date is greater than today /// /// The date to check /// True if the date is greater that today (ie. at least the day of tomorrow) public static bool DateGreaterThanToday(string firstDate) { DateTime first = DateTime.Parse(firstDate); first = new DateTime(first.Year, first.Month, first.Day); DateTime today = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day); TimeSpan TS = new TimeSpan(first.Ticks - today.Ticks); if (TS.Days > 0) return true; else return false; } /// /// Check if a date is greater than or equal today /// /// The date to check /// True if the date is greater that or equal today (ie. at least today or the day of tomorrow) public static bool DateGreaterThanOrEqualToday(string firstDate) { DateTime first = DateTime.Parse(firstDate); first = new DateTime(first.Year, first.Month, first.Day); DateTime today = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day); TimeSpan TS = new TimeSpan(first.Ticks - today.Ticks); if (TS.Days >= 0) return true; else return false; } /// /// Get the current date /// /// Current date i xml format (ToString("s")) public static string CurrentDate() { return DateTime.Now.ToString("s"); } /// /// Add a value to a date /// /// The Date to user /// The type to add: "y": year, "m": month, "d": day, "h": hour, "min": minutes, "s": seconds /// An integer value to add /// A date in xml format (ToString("s")) public static string DateAdd(string Date, string AddType, int add) { return DateAddWithDateTimeObject(DateTime.Parse(Date), AddType, add); } /// /// Get the day of week from a date matching the current culture settings /// /// The date to use /// A string with the DayOfWeek matching the current contexts culture settings public static string GetWeekDay(string Date) { return DateTime.Parse(Date).ToString("dddd"); } /// /// Add a value to a date. Similar to the other overload, but uses a datetime object instead of a string /// /// The Date to user /// The type to add: "y": year, "m": month, "d": day, "h": hour, "min": minutes, "s": seconds /// An integer value to add /// A date in xml format (ToString("s")) public static string DateAddWithDateTimeObject(DateTime Date, string AddType, int add) { switch (AddType.ToLower()) { case "y": Date = Date.AddYears(add); break; case "m": Date = Date.AddMonths(add); break; case "d": Date = Date.AddDays(add); break; case "h": Date = Date.AddHours(add); break; case "min": Date = Date.AddMinutes(add); break; case "s": Date = Date.AddSeconds(add); break; } return Date.ToString("s"); } /// /// Return the difference between 2 dates, in either minutes, seconds or years. /// /// The first date. /// The second date. /// format to return, can only be: s,m or y: s = seconds, m = minutes, y = years. /// A timespan as a integer public static int DateDiff(string firstDate, string secondDate, string diffType) { TimeSpan TS = DateTime.Parse(firstDate).Subtract(DateTime.Parse(secondDate)); switch (diffType.ToLower()) { case "m": return Convert.ToInt32(TS.TotalMinutes); case "s": return Convert.ToInt32(TS.TotalSeconds); case "y": return Convert.ToInt32(TS.TotalDays / 365); } // return default return 0; } /// /// Formats a string to the specified formate. /// /// The date. /// The format, compatible with regular .net date formats /// A date in the new format as a string public static string FormatDateTime(string Date, string Format) { DateTime result; if (DateTime.TryParse(Date, out result)) return result.ToString(Format); return string.Empty; } /// /// Converts a string to Long Date and returns it as a string /// /// The date. /// if set to true the date will include time. /// The splitter between date and time. /// A Long Date as a string. public static string LongDate(string Date, bool WithTime, string TimeSplitter) { DateTime result; if (DateTime.TryParse(Date, out result)) { if (WithTime) return result.ToLongDateString() + TimeSplitter + result.ToLongTimeString(); return result.ToLongDateString(); } return string.Empty; } /// /// Checks whether the Culture with the specified name exixts in the standard .net cultureInfo. /// /// Name of the culture. /// public static bool CultureExists(string cultureName) { CultureInfo[] ci = CultureInfo.GetCultures(CultureTypes.AllCultures); CultureInfo c = Array.Find(ci, delegate(CultureInfo culture) { return culture.Name == cultureName; }); return c != null; } /// /// Converts a string to datetime in the longdate with day name format. /// /// The date. /// String between day name and date /// if set to true the datetiem will include time. /// String between date and time. /// Culture name. /// A datetime in the longdate formate with day name, as a string public static string LongDateWithDayName(string Date, string DaySplitter, bool WithTime, string TimeSplitter, string GlobalAlias) { if (!CultureExists(GlobalAlias)) return string.Empty; DateTime result; CultureInfo.GetCultureInfo(GlobalAlias); DateTimeFormatInfo dtInfo = CultureInfo.GetCultureInfo(GlobalAlias).DateTimeFormat; if (DateTime.TryParse(Date, dtInfo, DateTimeStyles.None, out result)) { if (WithTime) return result.ToString(dtInfo.LongDatePattern) + TimeSplitter + result.ToString(dtInfo.LongTimePattern); return result.ToString(dtInfo.LongDatePattern); } return string.Empty; } /// /// Converts a string to a Long Date and returns it as a string /// /// The date. /// A Long Date as a string. public static string LongDate(string Date) { DateTime result; if (DateTime.TryParse(Date, out result)) return result.ToLongDateString(); return string.Empty; } /// /// Converts a string to a Short Date and returns it as a string /// /// The date. /// A Short Date as a string. public static string ShortDate(string Date) { DateTime result; if (DateTime.TryParse(Date, out result)) return result.ToShortDateString(); return string.Empty; } /// /// Converts a string to a Short Date, with a specific culture, and returns it as a string /// /// The date. /// Culture name /// A short date with a specific culture, as a string public static string ShortDateWithGlobal(string Date, string GlobalAlias) { if (!CultureExists(GlobalAlias)) return string.Empty; DateTime result; if (DateTime.TryParse(Date, out result)) { DateTimeFormatInfo dtInfo = CultureInfo.GetCultureInfo(GlobalAlias).DateTimeFormat; return result.ToString(dtInfo.ShortDatePattern); } return string.Empty; } /// /// Converts a string to a Short Date with time, with a specific culture, and returns it as a string /// /// The date. /// Culture name /// A short date withi time, with a specific culture, as a string public static string ShortDateWithTimeAndGlobal(string Date, string GlobalAlias) { if (!CultureExists(GlobalAlias)) return string.Empty; DateTime result; if (DateTime.TryParse(Date, out result)) { DateTimeFormatInfo dtInfo = CultureInfo.GetCultureInfo(GlobalAlias).DateTimeFormat; return result.ToString(dtInfo.ShortDatePattern) + " " + result.ToString(dtInfo.ShortTimePattern); } return string.Empty; } /// /// Converts a datetime string to the ShortTime format. /// /// The date. /// public static string ShortTime(string Date) { DateTime result; if (DateTime.TryParse(Date, out result)) return result.ToShortTimeString(); return string.Empty; } /// /// Converts a datetime string to the ShortDate format. /// /// The date. /// if set to true the date will include time. /// String dividing date and time /// public static string ShortDate(string Date, bool WithTime, string TimeSplitter) { DateTime result; if (DateTime.TryParse(Date, out result)) { if (WithTime) return result.ToShortDateString() + TimeSplitter + result.ToLongTimeString(); return result.ToShortDateString(); } return string.Empty; } /// /// Replaces text line breaks with html line breaks /// /// The text. /// The text with text line breaks replaced with html linebreaks (
)
public static string ReplaceLineBreaks(string text) { if (bool.Parse(GlobalSettings.EditXhtmlMode)) return text.Replace("\n", "
\n"); else return text.Replace("\n", "
\n"); } /// /// Renders the content of a macro. Uses the normal template umbraco macro markup as input. /// This only works properly with xslt macros. /// Python and .ascx based macros will not render properly, as viewstate is not included. /// /// The macro markup to be rendered. /// The page id. /// The rendered macro as a string public static string RenderMacroContent(string Text, int PageId) { try { page p = new page(((IHasXmlNode)GetXmlNodeById(PageId.ToString()).Current).GetNode()); template t = new template(p.Template); Control c = t.parseStringBuilder(new StringBuilder(Text), p); StringWriter sw = new StringWriter(); HtmlTextWriter hw = new HtmlTextWriter(sw); c.RenderControl(hw); return sw.ToString(); } catch (Exception ee) { return string.Format("", ee); } } /// /// Renders a template. /// /// The page id. /// The template id. /// The rendered template as a string public static string RenderTemplate(int PageId, int TemplateId) { try { if (UmbracoSettings.UseAspNetMasterPages) { System.Collections.Generic.Dictionary items = getCurrentContextItems(); if (!umbraco.presentation.UmbracoContext.Current.LiveEditingContext.Enabled) { HttpContext Context = HttpContext.Current; StringBuilder queryString = new StringBuilder(); const string ONE_QS_PARAM = "&{0}={1}"; foreach (object key in Context.Request.QueryString.Keys) { if (!key.ToString().ToLower().Equals("umbpageid") && !key.ToString().ToLower().Equals("alttemplate")) queryString.Append(string.Format(ONE_QS_PARAM, key, Context.Request.QueryString[key.ToString()])); } StringWriter sw = new StringWriter(); Context.Server.Execute( string.Format("/default.aspx?umbPageID={0}&alttemplate={1}{2}", PageId, new template(TemplateId).TemplateAlias, queryString), sw); // update the local page items again updateLocalContextItems(items, Context); return sw.ToString(); } else { return "RenderTemplate not supported in Canvas"; } } else { page p = new page(((IHasXmlNode)GetXmlNodeById(PageId.ToString()).Current).GetNode()); p.RenderPage(TemplateId); Control c = p.PageContentControl; StringWriter sw = new StringWriter(); HtmlTextWriter hw = new HtmlTextWriter(sw); c.RenderControl(hw); return sw.ToString(); } } catch (Exception ee) { return string.Format("", ee); } } private static System.Collections.Generic.Dictionary getCurrentContextItems() { IDictionary items = HttpContext.Current.Items; System.Collections.Generic.Dictionary currentItems = new Dictionary(); IDictionaryEnumerator ide = items.GetEnumerator(); while (ide.MoveNext()) { currentItems.Add(ide.Key, ide.Value); } return currentItems; } private static void updateLocalContextItems(IDictionary items, HttpContext Context) { Context.Items.Clear(); IDictionaryEnumerator ide = items.GetEnumerator(); while (ide.MoveNext()) { Context.Items.Add(ide.Key, ide.Value); } } /// /// Renders the default template for a specific page. /// /// The page id. /// The rendered template as a string. public static string RenderTemplate(int PageId) { try { if (UmbracoSettings.UseAspNetMasterPages) { if (!umbraco.presentation.UmbracoContext.Current.LiveEditingContext.Enabled) { HttpContext Context = HttpContext.Current; StringBuilder queryString = new StringBuilder(); const string ONE_QS_PARAM = "&{0}={1}"; foreach (object key in Context.Request.QueryString.Keys) { if (!key.ToString().ToLower().Equals("umbpageid")) queryString.Append(string.Format(ONE_QS_PARAM, key, Context.Request.QueryString[key.ToString()])); } StringWriter sw = new StringWriter(); Context.Server.Execute( string.Format("/default.aspx?umbPageID={0}{1}", PageId, queryString), sw); return sw.ToString(); } else { return "RenderTemplate not supported in Canvas"; } } else { return RenderTemplate(PageId, new page(((IHasXmlNode)GetXmlNodeById(PageId.ToString()).Current).GetNode()).Template); } } catch (Exception ee) { return string.Format("", ee); } } /// /// Registers the client script block. /// /// The key. /// The script. /// if set to true [add script tags]. public static void RegisterClientScriptBlock(string key, string script, bool addScriptTags) { Page p = HttpContext.Current.CurrentHandler as Page; if (p != null) p.ClientScript.RegisterClientScriptBlock(p.GetType(), key, script, addScriptTags); } /// /// Registers the client script include. /// /// The key. /// The URL. public static void RegisterStyleSheetFile(string key, string url) { Page p = HttpContext.Current.CurrentHandler as Page; if (p != null) { System.Web.UI.HtmlControls.HtmlGenericControl include = new System.Web.UI.HtmlControls.HtmlGenericControl("link"); include.ID = key; include.Attributes.Add("rel", "stylesheet"); include.Attributes.Add("type", "text/css"); include.Attributes.Add("href", url); if (p.Header != null) { if (p.Header.FindControl(key) == null) { p.Header.Controls.Add(include); } } else { //This is a fallback in case there is no header p.ClientScript.RegisterClientScriptBlock(p.GetType(), key, ""); } } } /// /// Registers the client script include. /// /// The key. /// The URL. public static void RegisterJavaScriptFile(string key, string url) { Page p = HttpContext.Current.CurrentHandler as Page; if (p != null) { if (ClientDependency.Core.Controls.ClientDependencyLoader.Instance == null) { System.Web.UI.HtmlControls.HtmlGenericControl include = new System.Web.UI.HtmlControls.HtmlGenericControl("script"); include.ID = key; include.Attributes.Add("type", "text/javascript"); include.Attributes.Add("src", url); if (p.Header != null) { if (p.Header.FindControl(key) == null) { p.Header.Controls.Add(include); } } else { //This is a fallback in case there is no header p.ClientScript.RegisterClientScriptInclude(p.GetType(), key, url); } } else { ClientDependency.Core.Controls.ClientDependencyLoader.Instance.RegisterDependency(url, ClientDependency.Core.ClientDependencyType.Javascript); } } } /// /// Adds a reference to the jQuery javascript file from the client/ui folder using "jQuery" as a key /// Recommended to use instead of RegisterJavaScriptFile for all nitros/packages that uses jQuery /// public static void AddJquery() { RegisterJavaScriptFile("jQuery", String.Format("{0}/ui/jquery.js", IOHelper.ResolveUrl(SystemDirectories.Umbraco_client))); } /// /// Strips all html from a string. /// /// The text. /// Returns the string without any html tags. public static string StripHtml(string text) { string pattern = @"<(.|\n)*?>"; return Regex.Replace(text, pattern, string.Empty); } /// /// Truncates a string if it's too long /// /// The text to eventually truncate /// The maximum number of characters (length) /// String to append if text is truncated (ie "...") /// A truncated string if text if longer than MaxLength appended with the addString parameters. If text is shorter /// then MaxLength then the full - non-truncated - string is returned public static string TruncateString(string Text, int MaxLength, string AddString) { if (Text.Length > MaxLength) return Text.Substring(0, MaxLength - AddString.Length) + AddString; else return Text; } /// /// Split a string into xml elements /// /// The full text to spil /// The separator /// An XPathNodeIterator containing the substrings in the format of public static XPathNodeIterator Split(string StringToSplit, string Separator) { string[] values = StringToSplit.Split(Convert.ToChar(Separator)); XmlDocument xd = new XmlDocument(); xd.LoadXml(""); foreach (string id in values) { XmlNode node = xmlHelper.addTextNode(xd, "value", id); xd.DocumentElement.AppendChild(node); } XPathNavigator xp = xd.CreateNavigator(); return xp.Select("/values"); } /// /// Removes the starting and ending paragraph tags in a string. /// /// The text. /// Returns the string without starting and endning paragraph tags public static string RemoveFirstParagraphTag(string text) { if (String.IsNullOrEmpty(text)) return ""; text = text.Trim().Replace("\n", string.Empty).Replace("\r", string.Empty); if (text.Length > 5) { if (text.ToUpper().Substring(0, 3) == "

") text = text.Substring(3, text.Length - 3); if (text.ToUpper().Substring(text.Length - 4, 4) == "

") text = text.Substring(0, text.Length - 4); } return text; } /// /// Replaces a specified value with a new one. /// /// The text. /// The old value. /// The new value. /// public static string Replace(string text, string oldValue, string newValue) { return text.Replace(oldValue, newValue); } /// /// Returns the Last index of the specified value /// /// The text. /// The value. /// Return the last index of a value as a integer public static int LastIndexOf(string Text, string Value) { return Text.LastIndexOf(Value); } /// /// Gets the prevalues from a umbraco DataType with the specified data type id. /// /// The data type id. /// Returns the prevalues as a XPathNodeIterator in the format: /// /// [value] /// /// public static XPathNodeIterator GetPreValues(int DataTypeId) { XmlDocument xd = new XmlDocument(); xd.LoadXml(""); using (IRecordsReader dr = SqlHelper.ExecuteReader("Select id, [value] from cmsDataTypeprevalues where DataTypeNodeId = @dataTypeId order by sortorder", SqlHelper.CreateParameter("@dataTypeId", DataTypeId))) { while (dr.Read()) { XmlNode n = xmlHelper.addTextNode(xd, "preValue", dr.GetString("value")); n.Attributes.Append(xmlHelper.addAttribute(xd, "id", dr.GetInt("id").ToString())); xd.DocumentElement.AppendChild(n); } } XPathNavigator xp = xd.CreateNavigator(); return xp.Select("/preValues"); } /// /// Gets the umbraco data type prevalue with the specified Id as string. /// /// The id. /// Returns the prevalue as a string public static string GetPreValueAsString(int Id) { try { return SqlHelper.ExecuteScalar("select [value] from cmsDataTypePreValues where id = @id", SqlHelper.CreateParameter("@id", Id)); } catch { return string.Empty; } } /// /// Gets the dictionary item with the specified key and it's child dictionary items. /// The language version is based on the culture of the current Url. /// /// The key. /// A XpathNodeIterator in the format: /// /// [dictionaryItemValue] /// /// public static XPathNodeIterator GetDictionaryItems(string Key) { XmlDocument xd = new XmlDocument(); xd.LoadXml(""); try { //int languageId = GetCurrentLanguageId(); int languageId = Language.GetByCultureCode(System.Threading.Thread.CurrentThread.CurrentUICulture.Name).id; Dictionary.DictionaryItem di = new Dictionary.DictionaryItem(Key); foreach (Dictionary.DictionaryItem item in di.Children) { XmlNode xe; try { if (languageId != 0) xe = xmlHelper.addTextNode(xd, "DictionaryItem", item.Value(languageId)); else xe = xmlHelper.addTextNode(xd, "DictionaryItem", item.Value()); } catch { xe = xmlHelper.addTextNode(xd, "DictionaryItem", string.Empty); } xe.Attributes.Append(xmlHelper.addAttribute(xd, "key", item.key)); xd.DocumentElement.AppendChild(xe); } } catch (Exception ee) { xd.DocumentElement.AppendChild( xmlHelper.addTextNode(xd, "Error", ee.ToString())); } XPathNavigator xp = xd.CreateNavigator(); return xp.Select("/"); } /// /// Gets the dictionary item with the specified key. /// /// The key. /// A dictionary items value as a string. public static string GetDictionaryItem(string Key) { try { Language l = Language.GetByCultureCode(System.Threading.Thread.CurrentThread.CurrentUICulture.Name); return new Dictionary.DictionaryItem(Key).Value(l.id); //return new Dictionary.DictionaryItem(Key).Value(GetCurrentLanguageId()); } catch (Exception errDictionary) { HttpContext.Current.Trace.Warn("library", "Error returning dictionary item '" + Key + "'", errDictionary); return string.Empty; } } /// /// Returns the ID of the current language. /// /// The ID of the current language, or 0 if it could not be determined. private static int GetCurrentLanguageId() { int languageId = 0; string pageId = HttpContext.Current.Items["pageID"] as string; if (pageId != null) { Domain[] domains = GetCurrentDomains(int.Parse(pageId)); if (domains != null && domains.Length >= 0) languageId = domains[0].Language.id; } return languageId; } /// /// Gets the current page. /// /// An XpathNodeIterator containing the current page as Xml. public static XPathNodeIterator GetXmlNodeCurrent() { try { XPathNavigator xp = UmbracoContext.Current.GetXml().CreateNavigator(); xp.MoveToId(HttpContext.Current.Items["pageID"].ToString()); return xp.Select("."); } catch { } XmlDocument xd = new XmlDocument(); xd.LoadXml("No current node exists"); return xd.CreateNavigator().Select("/"); } /// /// Gets the page with the specified id. /// /// The id. /// Returns the node with the specified id as xml in the form of a XPathNodeIterator public static XPathNodeIterator GetXmlNodeById(string id) { if (UmbracoContext.Current.GetXml().GetElementById(id) != null) { XPathNavigator xp = UmbracoContext.Current.GetXml().CreateNavigator(); xp.MoveToId(id); return xp.Select("."); } else { XmlDocument xd = new XmlDocument(); xd.LoadXml(string.Format("No published item exist with id {0}", id)); return xd.CreateNavigator().Select("."); } } /// /// Queries the umbraco Xml cache with the specified Xpath query /// /// The XPath query /// Returns nodes matching the xpath query as a XpathNodeIterator public static XPathNodeIterator GetXmlNodeByXPath(string xpathQuery) { XPathNavigator xp = content.Instance.XmlContent.CreateNavigator(); return xp.Select(xpathQuery); } /// /// Gets the entire umbraco xml cache. /// /// Returns the entire umbraco Xml cache as a XPathNodeIterator public static XPathNodeIterator GetXmlAll() { XPathNavigator xp = UmbracoContext.Current.GetXml().CreateNavigator(); return xp.Select("/root"); } /// /// Fetches a xml file from the specified path on the server. /// The path can be relative ("/path/to/file.xml") or absolute ("c:\folder\file.xml") /// /// The path. /// if set to true the path is relative. /// The xml file as a XpathNodeIterator public static XPathNodeIterator GetXmlDocument(string Path, bool Relative) { XmlDocument xmlDoc = new XmlDocument(); try { if (Relative) xmlDoc.Load( IOHelper.MapPath(Path) ); else xmlDoc.Load(Path); } catch (Exception err) { xmlDoc.LoadXml(string.Format("{2}", HttpContext.Current.Server.HtmlEncode(Path), Relative, err)); } XPathNavigator xp = xmlDoc.CreateNavigator(); return xp.Select("/"); } /// /// Fetches a xml file from the specified url. /// the Url can be a local url or even from a remote server. /// /// The URL. /// The xml file as a XpathNodeIterator public static XPathNodeIterator GetXmlDocumentByUrl(string Url) { XmlDocument xmlDoc = new XmlDocument(); WebRequest request = WebRequest.Create(Url); try { WebResponse response = request.GetResponse(); Stream responseStream = response.GetResponseStream(); XmlTextReader reader = new XmlTextReader(responseStream); xmlDoc.Load(reader); response.Close(); responseStream.Close(); } catch (Exception err) { xmlDoc.LoadXml(string.Format("{1}", HttpContext.Current.Server.HtmlEncode(Url), err)); } XPathNavigator xp = xmlDoc.CreateNavigator(); return xp.Select("/"); } /// /// Gets the XML document by URL Cached. /// /// The URL. /// The cache in seconds (so 900 would be 15 minutes). This is independent of the global cache refreshing, as it doesn't gets flushed on publishing (like the macros do) /// public static XPathNodeIterator GetXmlDocumentByUrl(string Url, int CacheInSeconds) { object urlCache = HttpContext.Current.Cache.Get("GetXmlDoc_" + Url); if (urlCache != null) return (XPathNodeIterator)urlCache; else { XPathNodeIterator result = GetXmlDocumentByUrl(Url); HttpContext.Current.Cache.Insert("GetXmlDoc_" + Url, result, null, DateTime.Now.Add(new TimeSpan(0, 0, CacheInSeconds)), TimeSpan.Zero, System.Web.Caching.CacheItemPriority.Low, null); return result; } } /// /// Returns the Xpath query for a node with the specified id /// /// The id. /// The Xpath query for the node with the specified id as a string public static string QueryForNode(string id) { string XPathQuery = string.Empty; if (UmbracoContext.Current.GetXml().GetElementById(id) != null) { string[] path = UmbracoContext.Current.GetXml().GetElementById(id).Attributes["path"].Value.Split((",").ToCharArray()); for (int i = 1; i < path.Length; i++) { if (i > 1) XPathQuery += "/node [@id = " + path[i] + "]"; else XPathQuery += " [@id = " + path[i] + "]"; } } return XPathQuery; } /// /// Helper function to get a value from a comma separated string. Usefull to get /// a node identifier from a Page's path string /// /// The comma separated string /// The index to be returned /// A string with the value of the index public static string GetNodeFromLevel(string path, int level) { try { string[] newPath = path.Split(','); if (newPath.Length >= level) return newPath[level].ToString(); else return string.Empty; } catch { return ""; } } /// /// Sends an e-mail using the System.Net.Mail.MailMessage object /// /// The sender of the e-mail /// The recipient of the e-mail /// E-mail subject /// The complete content of the e-mail /// Set to true when using Html formatted mails public static void SendMail(string FromMail, string ToMail, string Subject, string Body, bool IsHtml) { try { // create the mail message MailMessage mail = new MailMessage(FromMail.Trim(), ToMail.Trim()); // populate the message mail.Subject = Subject; if (IsHtml) mail.IsBodyHtml = true; else mail.IsBodyHtml = false; mail.Body = Body; // send it SmtpClient smtpClient = new SmtpClient(); smtpClient.Send(mail); } catch (Exception ee) { Log.Add(LogTypes.Error, -1, string.Format("umbraco.library.SendMail: Error sending mail. Exception: {0}", ee)); } } /// /// These random methods are from Eli Robillards blog - kudos for the work :-) /// http://weblogs.asp.net/erobillard/archive/2004/05/06/127374.aspx /// /// Get a Random object which is cached between requests. /// The advantage over creating the object locally is that the .Next /// call will always return a new value. If creating several times locally /// with a generated seed (like millisecond ticks), the same number can be /// returned. /// /// A Random object which is cached between calls. public static Random GetRandom(int seed) { Random r = (Random)HttpContext.Current.Cache.Get("RandomNumber"); if (r == null) { if (seed == 0) r = new Random(); else r = new Random(seed); HttpContext.Current.Cache.Insert("RandomNumber", r); } return r; } /// /// GetRandom with no parameters. /// /// A Random object which is cached between calls. public static Random GetRandom() { return GetRandom(0); } /// /// Get any value from the current Request collection. Please note that there also specialized methods for /// Querystring, Form, Servervariables and Cookie collections /// /// Name of the Request element to be returned /// A string with the value of the Requested element public static string Request(string key) { if (HttpContext.Current.Request[key] != null) return HttpContext.Current.Request[key]; else return string.Empty; } /// /// Changes the mime type of the current page. /// /// The mime type (like text/xml) public static void ChangeContentType(string MimeType) { if (!String.IsNullOrEmpty(MimeType)) { HttpContext.Current.Response.ContentType = MimeType; } } /// /// Get any value from the current Items collection. /// /// Name of the Items element to be returned /// A string with the value of the Items element public static string ContextKey(string key) { if (HttpContext.Current.Items[key] != null) return HttpContext.Current.Items[key].ToString(); else return string.Empty; } /// /// Get any value from the current Http Items collection /// /// Name of the Item element to be returned /// A string with the value of the Requested element public static string GetHttpItem(string key) { if (HttpContext.Current.Items[key] != null) return HttpContext.Current.Items[key].ToString(); else return string.Empty; } /// /// Get any value from the current Form collection /// /// Name of the Form element to be returned /// A string with the value of the form element public static string RequestForm(string key) { if (HttpContext.Current.Request.Form[key] != null) return HttpContext.Current.Request.Form[key]; else return string.Empty; } /// /// Get any value from the current Querystring collection /// /// Name of the querystring element to be returned /// A string with the value of the querystring element public static string RequestQueryString(string key) { if (HttpContext.Current.Request.QueryString[key] != null) return HttpContext.Current.Request.QueryString[key]; else return string.Empty; } /// /// Get any value from the users cookie collection /// /// Name of the cookie to return /// A string with the value of the cookie public static string RequestCookies(string key) { if (HttpContext.Current.Request.Cookies[key] != null) return HttpContext.Current.Request.Cookies[key].Value; else return string.Empty; } /// /// Get any element from the server variables collection /// /// The key for the element to be returned /// A string with the value of the requested element public static string RequestServerVariables(string key) { if (HttpContext.Current.Request.ServerVariables[key] != null) return HttpContext.Current.Request.ServerVariables[key]; else return string.Empty; } /// /// Get any element from current user session /// /// The key for the element to be returned /// A string with the value of the requested element public static string Session(string key) { if (HttpContext.Current.Session != null && HttpContext.Current.Session[key] != null) return HttpContext.Current.Session[key].ToString(); else return string.Empty; } /// /// Returns the current ASP.NET session identifier /// /// The current ASP.NET session identifier public static string SessionId() { if (HttpContext.Current.Session != null) return HttpContext.Current.Session.SessionID; else return string.Empty; } /// /// URL-encodes a string /// /// The string to be encoded /// A URL-encoded string public static string UrlEncode(string Text) { return HttpUtility.UrlEncode(Text); } /// /// HTML-encodes a string /// /// The string to be encoded /// A HTML-encoded string public static string HtmlEncode(string Text) { return HttpUtility.HtmlEncode(Text); } public static Relation[] GetRelatedNodes(int NodeId) { return new CMSNode(NodeId).Relations; } /// /// Gets the related nodes, of the node with the specified Id, as XML. /// /// The node id. /// The related nodes as a XpathNodeIterator in the format: /// /// /// [standard umbraco node Xml] /// /// /// public static XPathNodeIterator GetRelatedNodesAsXml(int NodeId) { XmlDocument xd = new XmlDocument(); xd.LoadXml(""); var rels = new CMSNode(NodeId).Relations; foreach (Relation r in rels) { XmlElement n = xd.CreateElement("relation"); n.AppendChild(xmlHelper.addCDataNode(xd, "comment", r.Comment)); n.Attributes.Append(xmlHelper.addAttribute(xd, "typeId", r.RelType.Id.ToString())); n.Attributes.Append(xmlHelper.addAttribute(xd, "typeName", r.RelType.Name)); n.Attributes.Append(xmlHelper.addAttribute(xd, "createDate", r.CreateDate.ToString())); n.Attributes.Append(xmlHelper.addAttribute(xd, "parentId", r.Parent.Id.ToString())); n.Attributes.Append(xmlHelper.addAttribute(xd, "childId", r.Child.Id.ToString())); // Append the node that isn't the one we're getting the related nodes from if (NodeId == r.Child.Id) n.AppendChild(r.Parent.ToXml(xd, false)); else n.AppendChild(r.Child.ToXml(xd, false)); xd.DocumentElement.AppendChild(n); } XPathNavigator xp = xd.CreateNavigator(); return xp.Select("."); } /// /// Returns the identifier of the current page /// /// The identifier of the current page public int PageId() { if (_page != null) return _page.PageID; else return -1; } /// /// Returns the title of the current page /// /// The title of the current page public string PageName() { if (_page != null) return _page.PageName; else return string.Empty; } /// /// Returns any element from the currentpage including generic properties /// /// The name of the page element to return /// A string with the element value public string PageElement(string key) { if (_page != null) { if (_page.Elements[key] != null) return _page.Elements[key].ToString(); else return string.Empty; } else return string.Empty; } /// /// Cleans the spified string with tidy /// /// The string to tidy. /// if set to true [Live Editing]. /// public static string Tidy(string StringToTidy, bool LiveEditing) { return cms.helpers.xhtml.TidyHtml(StringToTidy); } #endregion #region Template Control Mapping Functions /// /// Creates an Umbraco item for the specified field of the specified node. /// This brings the umbraco:Item element functionality to XSLT documents, /// which enables Live Editing of XSLT generated content. /// /// The ID of the node to create. /// Name of the field to create. /// An Umbraco item. public string Item(int nodeId, string fieldName) { return Item(nodeId, fieldName, null); } /// /// Creates an Umbraco item for the specified field of the specified node. /// This brings the umbraco:Item element functionality to XSLT documents, /// which enables Live Editing of XSLT generated content. /// /// The ID of the node to create. /// Name of the field to create. /// /// Value that is displayed to the user, which can be different from the field value. /// Ignored if null. /// Inside an XSLT document, an XPath expression might be useful to generate this value, /// analogous to the functionality of the Xslt property of an umbraco:Item element. /// /// An Umbraco item. public string Item(int nodeId, string fieldName, string displayValue) { // require a field name if (String.IsNullOrEmpty(fieldName)) throw new ArgumentNullException("fieldName"); // encode the display value, if present, as an inline XSLT expression // escaping is disabled, since the user can choose to set // disable-output-escaping="yes" on the value-of element calling this function. string xslt = displayValue == null ? String.Empty : string.Format("xslt=\"'{0}'\" xsltdisableescaping=\"true\"", HttpUtility.HtmlEncode(displayValue).Replace("'", "&apos;")); // return a placeholder, the actual item will be created later on // in the CreateControlsFromText method of macro return string.Format("[[[[umbraco:Item nodeId=\"{0}\" field=\"{1}\" {2}]]]]", nodeId, fieldName, xslt); } #endregion } }