diff --git a/src/Umbraco.Core/Services/ContentService.cs b/src/Umbraco.Core/Services/ContentService.cs
index 18b768658e..86a176ee19 100644
--- a/src/Umbraco.Core/Services/ContentService.cs
+++ b/src/Umbraco.Core/Services/ContentService.cs
@@ -449,7 +449,7 @@ namespace Umbraco.Core.Services
{
try
{
- RePublishAllDo();
+ RebuildXmlStructures();
return true;
}
catch (Exception ex)
@@ -470,7 +470,7 @@ namespace Umbraco.Core.Services
{
try
{
- RePublishAllDo(contentTypeIds);
+ RebuildXmlStructures(contentTypeIds);
}
catch (Exception ex)
{
@@ -1152,11 +1152,18 @@ namespace Umbraco.Core.Services
#region Private Methods
+ //TODO: WE should make a base class for ContentService and MediaService to share!
+ // currently we have this logic duplicated (nearly the same) for media types and soon to be member types
+
///
- /// Rebuilds all xml content in the cmsContentXml table for all published documents
+ /// Rebuilds all xml content in the cmsContentXml table for all documents
///
+ ///
+ /// Only rebuild the xml structures for the content type ids passed in, if none then rebuilds the structures
+ /// for all content
+ ///
/// True if publishing succeeded, otherwise False
- private void RePublishAllDo(params int[] contentTypeIds)
+ private void RebuildXmlStructures(params int[] contentTypeIds)
{
using (new WriteLock(Locker))
{
@@ -1165,7 +1172,7 @@ namespace Umbraco.Core.Services
var uow = _uowProvider.GetUnitOfWork();
using (var repository = _repositoryFactory.CreateContentRepository(uow))
{
- if (!contentTypeIds.Any())
+ if (contentTypeIds.Any() == false)
{
//Remove all Document records from the cmsContentXml table (DO NOT REMOVE Media/Members!)
uow.Database.Execute(@"DELETE FROM cmsContentXml WHERE nodeId IN
@@ -1207,7 +1214,7 @@ namespace Umbraco.Core.Services
uow.Database.Insert(poco);
}
}
- Audit.Add(AuditTypes.Publish, "RePublish All completed, the xml has been regenerated in the database", 0, -1);
+ Audit.Add(AuditTypes.Publish, "RebuildXmlStructures completed, the xml has been regenerated in the database", 0, -1);
}
}
diff --git a/src/Umbraco.Core/Services/ContentTypeService.cs b/src/Umbraco.Core/Services/ContentTypeService.cs
index 1c764d88cf..9d0a8265b6 100644
--- a/src/Umbraco.Core/Services/ContentTypeService.cs
+++ b/src/Umbraco.Core/Services/ContentTypeService.cs
@@ -144,7 +144,7 @@ namespace Umbraco.Core.Services
/// if they are required to be updated.
///
/// A tuple of a content type and a boolean indicating if it is new (HasIdentity was false before committing)
- private void UpdateContentXmlStructure(params IContentType[] contentTypes)
+ private void UpdateContentXmlStructure(params IContentTypeBase[] contentTypes)
{
var toUpdate = new List();
@@ -190,17 +190,33 @@ namespace Umbraco.Core.Services
}
}
- var typedContentService = _contentService as ContentService;
- if (typedContentService != null && toUpdate.Any())
+ if (toUpdate.Any())
{
- typedContentService.RePublishAll(toUpdate.Select(x => x.Id).ToArray());
+ var firstType = toUpdate.First();
+ //if it is a content type then call the rebuilding methods or content
+ if (firstType is IContentType)
+ {
+ var typedContentService = _contentService as ContentService;
+ if (typedContentService != null)
+ {
+ typedContentService.RePublishAll(toUpdate.Select(x => x.Id).ToArray());
+ }
+ else
+ {
+ //this should never occur, the content service should always be typed but we'll check anyways.
+ _contentService.RePublishAll();
+ }
+ }
+ else if (firstType is IMediaType)
+ {
+ //if it is a media type then call the rebuilding methods for media
+ var typedContentService = _mediaService as MediaService;
+ if (typedContentService != null)
+ {
+ typedContentService.RebuildXmlStructures(toUpdate.Select(x => x.Id).ToArray());
+ }
+ }
}
- else if (toUpdate.Any())
- {
- //this should never occur, the content service should always be typed but we'll check anyways.
- _contentService.RePublishAll();
- }
-
}
@@ -258,7 +274,7 @@ namespace Umbraco.Core.Services
uow.Commit();
}
- UpdateContentXmlStructure(asArray);
+ UpdateContentXmlStructure(asArray.Cast().ToArray());
}
SavedContentType.RaiseEvent(new SaveEventArgs(asArray, false), this);
Audit.Add(AuditTypes.Save, string.Format("Save ContentTypes performed by user"), userId, -1);
@@ -412,17 +428,22 @@ namespace Umbraco.Core.Services
{
if (SavingMediaType.IsRaisedEventCancelled(new SaveEventArgs(mediaType), this))
return;
-
- var uow = _uowProvider.GetUnitOfWork();
- using (var repository = _repositoryFactory.CreateMediaTypeRepository(uow))
- {
- mediaType.CreatorId = userId;
- repository.AddOrUpdate(mediaType);
- uow.Commit();
- SavedMediaType.RaiseEvent(new SaveEventArgs(mediaType, false), this);
- }
+ using (new WriteLock(Locker))
+ {
+ var uow = _uowProvider.GetUnitOfWork();
+ using (var repository = _repositoryFactory.CreateMediaTypeRepository(uow))
+ {
+ mediaType.CreatorId = userId;
+ repository.AddOrUpdate(mediaType);
+ uow.Commit();
+
+ }
+ UpdateContentXmlStructure(mediaType);
+ }
+
+ SavedMediaType.RaiseEvent(new SaveEventArgs(mediaType, false), this);
Audit.Add(AuditTypes.Save, string.Format("Save MediaType performed by user"), userId, mediaType.Id);
}
@@ -438,22 +459,26 @@ namespace Umbraco.Core.Services
if (SavingMediaType.IsRaisedEventCancelled(new SaveEventArgs(asArray), this))
return;
- var uow = _uowProvider.GetUnitOfWork();
- using (var repository = _repositoryFactory.CreateMediaTypeRepository(uow))
- {
+ using (new WriteLock(Locker))
+ {
+ var uow = _uowProvider.GetUnitOfWork();
+ using (var repository = _repositoryFactory.CreateMediaTypeRepository(uow))
+ {
- foreach (var mediaType in asArray)
- {
- mediaType.CreatorId = userId;
- repository.AddOrUpdate(mediaType);
- }
+ foreach (var mediaType in asArray)
+ {
+ mediaType.CreatorId = userId;
+ repository.AddOrUpdate(mediaType);
+ }
- //save it all in one go
- uow.Commit();
+ //save it all in one go
+ uow.Commit();
+ }
- SavedMediaType.RaiseEvent(new SaveEventArgs(asArray, false), this);
- }
+ UpdateContentXmlStructure(asArray.Cast().ToArray());
+ }
+ SavedMediaType.RaiseEvent(new SaveEventArgs(asArray, false), this);
Audit.Add(AuditTypes.Save, string.Format("Save MediaTypes performed by user"), userId, -1);
}
diff --git a/src/Umbraco.Core/Services/MediaService.cs b/src/Umbraco.Core/Services/MediaService.cs
index 77a24cdc03..4fed0f6e0c 100644
--- a/src/Umbraco.Core/Services/MediaService.cs
+++ b/src/Umbraco.Core/Services/MediaService.cs
@@ -698,6 +698,72 @@ namespace Umbraco.Core.Services
Audit.Add(AuditTypes.Save, "Save Media items performed by user", userId, -1);
}
+ ///
+ /// Rebuilds all xml content in the cmsContentXml table for all media
+ ///
+ ///
+ /// Only rebuild the xml structures for the content type ids passed in, if none then rebuilds the structures
+ /// for all media
+ ///
+ /// True if publishing succeeded, otherwise False
+ internal void RebuildXmlStructures(params int[] contentTypeIds)
+ {
+ using (new WriteLock(Locker))
+ {
+ var list = new List();
+
+ var uow = _uowProvider.GetUnitOfWork();
+ using (var repository = _repositoryFactory.CreateContentRepository(uow))
+ {
+ if (contentTypeIds.Any() == false)
+ {
+ //Remove all media records from the cmsContentXml table (DO NOT REMOVE Content/Members!)
+ uow.Database.Execute(@"DELETE FROM cmsContentXml WHERE nodeId IN
+ (SELECT DISTINCT cmsContentXml.nodeId FROM cmsContentXml
+ INNER JOIN umbracoNode ON cmsContentXml.nodeId = umbracoNode.id
+ WHERE nodeObjectType = @nodeObjectType)",
+ new {nodeObjectType = Constants.ObjectTypes.Media});
+
+ // Consider creating a Path query instead of recursive method:
+ // var query = Query.Builder.Where(x => x.Path.StartsWith("-1"));
+ var rootMedia = GetRootMedia();
+ foreach (var media in rootMedia)
+ {
+ list.Add(media);
+ list.AddRange(GetDescendants(media));
+ }
+ }
+ else
+ {
+ foreach (var id in contentTypeIds)
+ {
+ //first we'll clear out the data from the cmsContentXml table for this type
+ uow.Database.Execute(@"delete from cmsContentXml where nodeId in
+ (SELECT DISTINCT cmsContentXml.nodeId FROM cmsContentXml
+ INNER JOIN umbracoNode ON cmsContentXml.nodeId = umbracoNode.id
+ INNER JOIN cmsContent ON cmsContent.nodeId = umbracoNode.id
+ WHERE nodeObjectType = @nodeObjectType AND cmsContent.contentType = @contentTypeId)",
+ new {contentTypeId = id, nodeObjectType = Constants.ObjectTypes.Media});
+
+ //now get all media objects of this type and add to the list
+ list.AddRange(GetMediaOfMediaType(id));
+ }
+ }
+
+ foreach (var c in list)
+ {
+ //generate the xml
+ var xml = c.ToXml();
+ //create the dto to insert
+ var poco = new ContentXmlDto { NodeId = c.Id, Xml = xml.ToString(SaveOptions.None) };
+ //insert it into the database
+ uow.Database.Insert(poco);
+ }
+ }
+ Audit.Add(AuditTypes.Publish, "RebuildXmlStructures completed, the xml has been regenerated in the database", 0, -1);
+ }
+ }
+
///
/// Updates the Path and Level on a collection of objects
/// based on the Parent's Path and Level.