Fixes: #U4-2149 - updates the logic for changing aliases for any content type. Now if an alias changes for any content type, the

xml is regenerated for any entity that is of that content type. For DocumentType's this is slightly different because we regenerate
the xml for the doc type and any document of the doc type's descendant types.
This commit is contained in:
Shannon Deminick
2013-04-24 14:57:20 -10:00
parent a8029d1dc5
commit 0e8ffe528a
7 changed files with 213 additions and 31 deletions

View File

@@ -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
/// </remarks>
private void RegenerateXmlCaches()
{
_contentType.RebuildXmlStructuresForContent();
//special case for DocumentType's
if (_contentType is DocumentType)
{
umbraco.cms.businesslogic.web.Document.RePublishAll();
library.RefreshContent();
}
}

View File

@@ -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
/// <param name="xd"></param>
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)
{

View File

@@ -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
/// <summary>
/// Used to rebuild all of the xml structures for content of the current content type in the cmsContentXml table
/// </summary>
[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);
}
}
/// <summary>
/// Returns all content ids associated with this content type
/// </summary>
/// <returns></returns>
/// <remarks>
/// 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.
/// </remarks>
internal virtual IEnumerable<int> GetContentIdsForContentType()
{
var ids = new List<int>();
//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;
}
/// <summary>
/// Rebuilds the xml structure for the content item by id
/// </summary>
/// <param name="contentId"></param>
/// <remarks>
/// This is not thread safe
/// </remarks>
internal virtual void RebuildXmlStructureForContentItem(int contentId)
{
var xd = new XmlDocument();
try
{
new Content(contentId).XmlGenerate(xd);
}
catch (Exception ee)
{
LogHelper.Error<ContentType>("Error generating xml", ee);
}
}
/// <summary>
/// Clears all xml structures in the cmsContentXml table for the current content type
/// </summary>
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
/// <summary>
/// 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

View File

@@ -585,16 +585,7 @@ namespace umbraco.cms.businesslogic.member
FireAfterSave(e);
}
}
/// <summary>
/// Generates the xmlrepresentation of a member
/// </summary>
/// <param name="xd"></param>
public override void XmlGenerate(XmlDocument xd)
{
SaveXmlDocument(generateXmlWithoutSaving(xd));
}
/// <summary>
/// Xmlrepresentation of a member
/// </summary>

View File

@@ -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
/// <param name="id">MemberType id</param>
public MemberType(Guid id) : base(id) { }
#region Regenerate Xml Structures
/// <summary>
/// Rebuilds the xml structure for the member item by id
/// </summary>
/// <param name="contentId"></param>
/// <remarks>
/// This is not thread safe
/// </remarks>
internal override void RebuildXmlStructureForContentItem(int contentId)
{
var xd = new XmlDocument();
try
{
new Member(contentId).XmlGenerate(xd);
}
catch (Exception ee)
{
LogHelper.Error<MemberType>("Error generating xml", ee);
}
}
#endregion
/// <summary>
/// Used to persist object changes to the database. In Version3.0 it's just a stub for future compatibility
/// </summary>

View File

@@ -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<Document>("Error generating xml", ee);
}
}
dr.Close();

View File

@@ -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
/// <summary>
/// This will return all PUBLISHED content Ids that are of this content type or any descendant types as well.
/// </summary>
/// <returns></returns>
internal override IEnumerable<int> GetContentIdsForContentType()
{
var ids = new List<int>();
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<int?>("SELECT nodeId FROM cmsContentType WHERE masterContentType=@contentTypeId",
SqlHelper.CreateParameter("@contentTypeId", currentContentTypeId));
}
return ids;
}
/// <summary>
/// Rebuilds the xml structure for the content item by id
/// </summary>
/// <param name="contentId"></param>
/// <remarks>
/// This is not thread safe
/// </remarks>
internal override void RebuildXmlStructureForContentItem(int contentId)
{
var xd = new XmlDocument();
try
{
new Document(contentId).XmlGenerate(xd);
}
catch (Exception ee)
{
LogHelper.Error<DocumentType>("Error generating xml", ee);
}
}
/// <summary>
/// Clears all xml structures in the cmsContentXml table for the current content type and any of it's descendant types
/// </summary>
/// <remarks>
/// This is not thread safe
/// </remarks>
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<int?>("SELECT nodeId FROM cmsContentType WHERE masterContentType=@contentTypeId",
SqlHelper.CreateParameter("@contentTypeId", currentContentTypeId));
}
}
#endregion
public void RemoveTemplate(int templateId)
{
// remove if default template