diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/controls/ContentTypeControlNew.ascx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/controls/ContentTypeControlNew.ascx.cs index 780fab6246..a4fa8f65b3 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/controls/ContentTypeControlNew.ascx.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/controls/ContentTypeControlNew.ascx.cs @@ -276,6 +276,10 @@ namespace umbraco.controls { _contentType = new cms.businesslogic.media.MediaType(docTypeId); } + else if (Request.Path.ToLowerInvariant().Contains("editmembertype.aspx")) + { + _contentType = new cms.businesslogic.member.MemberType(docTypeId); + } else { _contentType = new ContentType(docTypeId); @@ -291,9 +295,11 @@ namespace umbraco.controls /// private void RegenerateXmlCaches() { + _contentType.RebuildXmlStructuresForContent(); + + //special case for DocumentType's if (_contentType is DocumentType) { - umbraco.cms.businesslogic.web.Document.RePublishAll(); library.RefreshContent(); } } diff --git a/src/umbraco.cms/businesslogic/Content.cs b/src/umbraco.cms/businesslogic/Content.cs index d8c30138ae..3e5bfacb3d 100644 --- a/src/umbraco.cms/businesslogic/Content.cs +++ b/src/umbraco.cms/businesslogic/Content.cs @@ -5,6 +5,7 @@ using System.Linq; using System.Data; using System.Xml; using Umbraco.Core.IO; +using Umbraco.Core.Logging; using umbraco.cms.businesslogic.property; using umbraco.cms.businesslogic.propertytype; using umbraco.DataLayer; @@ -416,8 +417,7 @@ namespace umbraco.cms.businesslogic /// public virtual void XmlGenerate(XmlDocument xd) { - XmlNode node = generateXmlWithoutSaving(xd); - SaveXmlDocument(node); + SaveXmlDocument(generateXmlWithoutSaving(xd)); } public virtual void XmlPopulate(XmlDocument xd, ref XmlNode x, bool Deep) @@ -428,27 +428,27 @@ namespace umbraco.cms.businesslogic x.AppendChild(p.ToXml(xd)); // attributes - x.Attributes.Append(xmlHelper.addAttribute(xd, "id", this.Id.ToString())); - x.Attributes.Append(xmlHelper.addAttribute(xd, "version", this.Version.ToString())); + x.Attributes.Append(XmlHelper.AddAttribute(xd, "id", this.Id.ToString())); + x.Attributes.Append(XmlHelper.AddAttribute(xd, "version", this.Version.ToString())); if (this.Level > 1) - x.Attributes.Append(xmlHelper.addAttribute(xd, "parentID", this.Parent.Id.ToString())); + x.Attributes.Append(XmlHelper.AddAttribute(xd, "parentID", this.Parent.Id.ToString())); else - x.Attributes.Append(xmlHelper.addAttribute(xd, "parentID", "-1")); - x.Attributes.Append(xmlHelper.addAttribute(xd, "level", this.Level.ToString())); - x.Attributes.Append(xmlHelper.addAttribute(xd, "writerID", this.User.Id.ToString())); + x.Attributes.Append(XmlHelper.AddAttribute(xd, "parentID", "-1")); + x.Attributes.Append(XmlHelper.AddAttribute(xd, "level", this.Level.ToString())); + x.Attributes.Append(XmlHelper.AddAttribute(xd, "writerID", this.User.Id.ToString())); if (this.ContentType != null) - x.Attributes.Append(xmlHelper.addAttribute(xd, "nodeType", this.ContentType.Id.ToString())); - x.Attributes.Append(xmlHelper.addAttribute(xd, "template", "0")); - x.Attributes.Append(xmlHelper.addAttribute(xd, "sortOrder", this.sortOrder.ToString())); - x.Attributes.Append(xmlHelper.addAttribute(xd, "createDate", this.CreateDateTime.ToString("s"))); - x.Attributes.Append(xmlHelper.addAttribute(xd, "updateDate", this.VersionDate.ToString("s"))); - x.Attributes.Append(xmlHelper.addAttribute(xd, "nodeName", this.Text)); + x.Attributes.Append(XmlHelper.AddAttribute(xd, "nodeType", this.ContentType.Id.ToString())); + x.Attributes.Append(XmlHelper.AddAttribute(xd, "template", "0")); + x.Attributes.Append(XmlHelper.AddAttribute(xd, "sortOrder", this.sortOrder.ToString())); + x.Attributes.Append(XmlHelper.AddAttribute(xd, "createDate", this.CreateDateTime.ToString("s"))); + x.Attributes.Append(XmlHelper.AddAttribute(xd, "updateDate", this.VersionDate.ToString("s"))); + x.Attributes.Append(XmlHelper.AddAttribute(xd, "nodeName", this.Text)); if (this.Text != null) - x.Attributes.Append(xmlHelper.addAttribute(xd, "urlName", this.Text.Replace(" ", "").ToLower())); - x.Attributes.Append(xmlHelper.addAttribute(xd, "writerName", this.User.Name)); + x.Attributes.Append(XmlHelper.AddAttribute(xd, "urlName", this.Text.Replace(" ", "").ToLower())); + x.Attributes.Append(XmlHelper.AddAttribute(xd, "writerName", this.User.Name)); if (this.ContentType != null) - x.Attributes.Append(xmlHelper.addAttribute(xd, "nodeTypeAlias", this.ContentType.Alias)); - x.Attributes.Append(xmlHelper.addAttribute(xd, "path", this.Path)); + x.Attributes.Append(XmlHelper.AddAttribute(xd, "nodeTypeAlias", this.ContentType.Alias)); + x.Attributes.Append(XmlHelper.AddAttribute(xd, "path", this.Path)); if (Deep) { diff --git a/src/umbraco.cms/businesslogic/ContentType.cs b/src/umbraco.cms/businesslogic/ContentType.cs index 9634047464..93e5cede1c 100644 --- a/src/umbraco.cms/businesslogic/ContentType.cs +++ b/src/umbraco.cms/businesslogic/ContentType.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.Threading; using System.Runtime.CompilerServices; using System.Linq; +using System.Xml; using Umbraco.Core; using Umbraco.Core.Logging; using umbraco.cms.businesslogic.web; @@ -282,6 +283,84 @@ namespace umbraco.cms.businesslogic #region Public Properties + #region Regenerate Xml Structures + + /// + /// Used to rebuild all of the xml structures for content of the current content type in the cmsContentXml table + /// + [MethodImpl(MethodImplOptions.Synchronized)] + internal void RebuildXmlStructuresForContent() + { + //Clears all xml structures in the cmsContentXml table for the current content type + ClearXmlStructuresForContent(); + foreach (var i in GetContentIdsForContentType()) + { + RebuildXmlStructureForContentItem(i); + } + } + + /// + /// Returns all content ids associated with this content type + /// + /// + /// + /// This will generally just return the content ids associated with this content type but in the case + /// of a DocumentType where we can have inherited types, this will return all content Ids that are of + /// this content type or any descendant types as well. + /// + internal virtual IEnumerable GetContentIdsForContentType() + { + var ids = new List(); + //get all the content item ids of the current content type + using (var dr = SqlHelper.ExecuteReader(@"SELECT DISTINCT cmsContent.nodeId FROM cmsContent + INNER JOIN cmsContentType ON cmsContent.contentType = cmsContentType.nodeId + WHERE cmsContentType.nodeId = @nodeId", + SqlHelper.CreateParameter("@nodeId", this.Id))) + { + while (dr.Read()) + { + ids.Add(dr.GetInt("nodeId")); + } + dr.Close(); + } + return ids; + } + + /// + /// Rebuilds the xml structure for the content item by id + /// + /// + /// + /// This is not thread safe + /// + internal virtual void RebuildXmlStructureForContentItem(int contentId) + { + var xd = new XmlDocument(); + try + { + new Content(contentId).XmlGenerate(xd); + } + catch (Exception ee) + { + LogHelper.Error("Error generating xml", ee); + } + } + + /// + /// Clears all xml structures in the cmsContentXml table for the current content type + /// + internal virtual void ClearXmlStructuresForContent() + { + //Remove all items from the cmsContentXml table that are of this current content type + SqlHelper.ExecuteNonQuery(@"DELETE FROM cmsContentXml WHERE nodeId IN + (SELECT DISTINCT cmsContent.nodeId FROM cmsContent + INNER JOIN cmsContentType ON cmsContent.contentType = cmsContentType.nodeId + WHERE cmsContentType.nodeId = @nodeId)", + SqlHelper.CreateParameter("@nodeId", this.Id)); + } + + #endregion + /// /// Get or Sets the Container status of the Content Type. A Container Content Type doesn't show its children in the tree, /// but instead adds a tab when edited showing its children in a grid diff --git a/src/umbraco.cms/businesslogic/member/Member.cs b/src/umbraco.cms/businesslogic/member/Member.cs index e94ee3e642..958994e794 100644 --- a/src/umbraco.cms/businesslogic/member/Member.cs +++ b/src/umbraco.cms/businesslogic/member/Member.cs @@ -585,16 +585,7 @@ namespace umbraco.cms.businesslogic.member FireAfterSave(e); } } - - /// - /// Generates the xmlrepresentation of a member - /// - /// - public override void XmlGenerate(XmlDocument xd) - { - SaveXmlDocument(generateXmlWithoutSaving(xd)); - } - + /// /// Xmlrepresentation of a member /// diff --git a/src/umbraco.cms/businesslogic/member/MemberType.cs b/src/umbraco.cms/businesslogic/member/MemberType.cs index 30b04b5b23..3e204f512a 100644 --- a/src/umbraco.cms/businesslogic/member/MemberType.cs +++ b/src/umbraco.cms/businesslogic/member/MemberType.cs @@ -1,6 +1,7 @@ using System; using System.Data; using System.Xml; +using Umbraco.Core.Logging; using umbraco.cms.businesslogic.propertytype; using System.Linq; using umbraco.BusinessLogic; @@ -27,6 +28,30 @@ namespace umbraco.cms.businesslogic.member /// MemberType id public MemberType(Guid id) : base(id) { } + #region Regenerate Xml Structures + + /// + /// Rebuilds the xml structure for the member item by id + /// + /// + /// + /// This is not thread safe + /// + internal override void RebuildXmlStructureForContentItem(int contentId) + { + var xd = new XmlDocument(); + try + { + new Member(contentId).XmlGenerate(xd); + } + catch (Exception ee) + { + LogHelper.Error("Error generating xml", ee); + } + } + + #endregion + /// /// Used to persist object changes to the database. In Version3.0 it's just a stub for future compatibility /// diff --git a/src/umbraco.cms/businesslogic/web/Document.cs b/src/umbraco.cms/businesslogic/web/Document.cs index 925cdf2bdf..f2d4c47b0f 100644 --- a/src/umbraco.cms/businesslogic/web/Document.cs +++ b/src/umbraco.cms/businesslogic/web/Document.cs @@ -7,6 +7,7 @@ using System.Threading; using System.Web; using System.Xml; using Umbraco.Core.IO; +using Umbraco.Core.Logging; using umbraco.BusinessLogic; using umbraco.BusinessLogic.Actions; using umbraco.cms.businesslogic.property; @@ -655,8 +656,7 @@ order by {1} } catch (Exception ee) { - Log.Add(LogTypes.Error, User.GetUser(0), dr.GetInt("nodeId"), - string.Format("Error generating xml: {0}", ee)); + LogHelper.Error("Error generating xml", ee); } } dr.Close(); diff --git a/src/umbraco.cms/businesslogic/web/DocumentType.cs b/src/umbraco.cms/businesslogic/web/DocumentType.cs index f254e1af74..a8af88fd6a 100644 --- a/src/umbraco.cms/businesslogic/web/DocumentType.cs +++ b/src/umbraco.cms/businesslogic/web/DocumentType.cs @@ -4,6 +4,7 @@ using System.Data; using System.Text; using System.Xml; using System.Linq; +using Umbraco.Core.Logging; using umbraco.BusinessLogic; using umbraco.cms.businesslogic.propertytype; using umbraco.DataLayer; @@ -294,6 +295,86 @@ namespace umbraco.cms.businesslogic.web #region Public Methods + #region Regenerate Xml Structures + + /// + /// This will return all PUBLISHED content Ids that are of this content type or any descendant types as well. + /// + /// + internal override IEnumerable GetContentIdsForContentType() + { + var ids = new List(); + int? currentContentTypeId = this.Id; + while (currentContentTypeId != null) + { + //get all the content item ids of the current content type + using (var dr = SqlHelper.ExecuteReader(@"SELECT DISTINCT cmsDocument.nodeId FROM cmsDocument + INNER JOIN cmsContent ON cmsContent.nodeId = cmsDocument.nodeId + INNER JOIN cmsContentType ON cmsContent.contentType = cmsContentType.nodeId + WHERE cmsContentType.nodeId = @contentTypeId AND cmsDocument.published = 1", + SqlHelper.CreateParameter("@contentTypeId", currentContentTypeId))) + { + while (dr.Read()) + { + ids.Add(dr.GetInt("nodeId")); + } + dr.Close(); + } + + //lookup the child content type if there is one + currentContentTypeId = SqlHelper.ExecuteScalar("SELECT nodeId FROM cmsContentType WHERE masterContentType=@contentTypeId", + SqlHelper.CreateParameter("@contentTypeId", currentContentTypeId)); + } + return ids; + } + + /// + /// Rebuilds the xml structure for the content item by id + /// + /// + /// + /// This is not thread safe + /// + internal override void RebuildXmlStructureForContentItem(int contentId) + { + var xd = new XmlDocument(); + try + { + new Document(contentId).XmlGenerate(xd); + } + catch (Exception ee) + { + LogHelper.Error("Error generating xml", ee); + } + } + + /// + /// Clears all xml structures in the cmsContentXml table for the current content type and any of it's descendant types + /// + /// + /// This is not thread safe + /// + internal override void ClearXmlStructuresForContent() + { + int? currentContentTypeId = this.Id; + while (currentContentTypeId != null) + { + //Remove all items from the cmsContentXml table that are of this current content type + SqlHelper.ExecuteNonQuery(@"DELETE FROM cmsContentXml WHERE nodeId IN + (SELECT DISTINCT cmsContent.nodeId FROM cmsContent + INNER JOIN cmsContentType ON cmsContent.contentType = cmsContentType.nodeId + WHERE cmsContentType.nodeId = @contentTypeId)", + SqlHelper.CreateParameter("@contentTypeId", currentContentTypeId)); + + //lookup the child content type if there is one + currentContentTypeId = SqlHelper.ExecuteScalar("SELECT nodeId FROM cmsContentType WHERE masterContentType=@contentTypeId", + SqlHelper.CreateParameter("@contentTypeId", currentContentTypeId)); + } + + } + + #endregion + public void RemoveTemplate(int templateId) { // remove if default template