diff --git a/src/Umbraco.Core/Services/ContentService.cs b/src/Umbraco.Core/Services/ContentService.cs index b225a3a5cb..973c665349 100644 --- a/src/Umbraco.Core/Services/ContentService.cs +++ b/src/Umbraco.Core/Services/ContentService.cs @@ -246,7 +246,7 @@ namespace Umbraco.Core.Services { using (var repository = _repositoryFactory.CreateContentRepository(_uowProvider.GetUnitOfWork())) { - var query = Query.Builder.Where(x => x.Path.StartsWith(content.Path)); + var query = Query.Builder.Where(x => x.Path.StartsWith(content.Path) && x.Id != content.Id); var contents = repository.GetByQuery(query); return contents; @@ -643,25 +643,7 @@ namespace Umbraco.Core.Services /// Optional Id of the User saving the Content public void Save(IContent content, int userId = -1) { - if (Saving.IsRaisedEventCancelled(new SaveEventArgs(content), this)) - return; - - var uow = _uowProvider.GetUnitOfWork(); - using (var repository = _repositoryFactory.CreateContentRepository(uow)) - { - SetWriter(content, userId); - - //Only change the publish state if the "previous" version was actually published - if (content.Published) - content.ChangePublishedState(PublishedState.Saved); - - repository.AddOrUpdate(content); - uow.Commit(); - } - - Saved.RaiseEvent(new SaveEventArgs(content, false), this); - - Audit.Add(AuditTypes.Save, "Save Content performed by user", userId == -1 ? 0 : userId, content.Id); + Save(content, true, userId); } /// @@ -917,6 +899,9 @@ namespace Umbraco.Core.Services return; SetWriter(content, userId); + var parent = GetById(parentId); + content.Path = string.Concat(parent.Path, ",", content.Id); + content.Level = parent.Level + 1; //If Content is being moved away from Recycle Bin, its state should be un-trashed if (content.Trashed && parentId != -20) @@ -931,7 +916,28 @@ namespace Umbraco.Core.Services //If Content is published, it should be (re)published from its new location if (content.Published) { - SaveAndPublish(content, userId); + //If Content is Publishable its saved and published + //otherwise we save the content without changing the publish state, and generate new xml because the Path, Level and Parent has changed. + if (IsPublishable(content)) + { + SaveAndPublish(content, userId); + } + else + { + Save(content, false, userId); + + using (var uow = _uowProvider.GetUnitOfWork()) + { + var xml = content.ToXml(); + var poco = new ContentXmlDto {NodeId = content.Id, Xml = xml.ToString(SaveOptions.None)}; + var exists = + uow.Database.FirstOrDefault("WHERE nodeId = @Id", new {Id = content.Id}) != + null; + int result = exists + ? uow.Database.Update(poco) + : Convert.ToInt32(uow.Database.Insert(poco)); + } + } } else { @@ -942,20 +948,10 @@ namespace Umbraco.Core.Services var children = GetChildren(content.Id); if (children.Any()) { - var parentPath = content.Path; - var parentLevel = content.Level; - var updatedDescendents = UpdatePathAndLevelOnChildren(children, parentPath, parentLevel); - - //collection of descendents that needs to be saved and published - var descendentsToSaveAndPublish = updatedDescendents.Where(x => x.Published); - foreach (var c in descendentsToSaveAndPublish) + foreach (var child in children) { - SaveAndPublish(c, userId); + Move(child, content.Id, userId); } - - //collection of descendents that only needs to be saved - var descendentsToSave = updatedDescendents.Where(x => x.Published == false); - Save(descendentsToSave, userId); } Moved.RaiseEvent(new MoveEventArgs(content, false, parentId), this); @@ -1162,6 +1158,35 @@ namespace Umbraco.Core.Services #region Private Methods + /// + /// Saves a single object + /// + /// The to save + /// Boolean indicating whether or not to change the Published state upon saving + /// Optional Id of the User saving the Content + private void Save(IContent content, bool changeState, int userId = -1) + { + if (Saving.IsRaisedEventCancelled(new SaveEventArgs(content), this)) + return; + + var uow = _uowProvider.GetUnitOfWork(); + using (var repository = _repositoryFactory.CreateContentRepository(uow)) + { + SetWriter(content, userId); + + //Only change the publish state if the "previous" version was actually published + if (changeState && content.Published) + content.ChangePublishedState(PublishedState.Saved); + + repository.AddOrUpdate(content); + uow.Commit(); + } + + Saved.RaiseEvent(new SaveEventArgs(content, false), this); + + Audit.Add(AuditTypes.Save, "Save Content performed by user", userId == -1 ? 0 : userId, content.Id); + } + /// /// Gets a flat list of decendents of content from parent id /// @@ -1222,32 +1247,6 @@ namespace Umbraco.Core.Services return true; } - /// - /// Updates the Path and Level on a collection of objects - /// based on the Parent's Path and Level. - /// - /// Collection of objects to update - /// Path of the Parent content - /// Level of the Parent content - /// Collection of updated objects - private List UpdatePathAndLevelOnChildren(IEnumerable children, string parentPath, int parentLevel) - { - var list = new List(); - foreach (var child in children) - { - child.Path = string.Concat(parentPath, ",", child.Id); - child.Level = parentLevel + 1; - list.Add(child); - - var grandkids = GetChildren(child.Id); - if (grandkids.Any()) - { - list.AddRange(UpdatePathAndLevelOnChildren(grandkids, child.Path, child.Level)); - } - } - return list; - } - /// /// Updates a content object with the User (id), who created the content. /// diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/moveOrCopy.aspx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/moveOrCopy.aspx.cs index afbd497d4d..aeab148ef7 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/moveOrCopy.aspx.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/moveOrCopy.aspx.cs @@ -261,26 +261,7 @@ namespace umbraco.dialogs var documentId = int.Parse(helper.Request("id")); var document = new Document(documentId); document.Move(int.Parse(helper.Request("copyTo"))); - if (document.Published) - { - //TODO HACK - Have to get the Document again, to get the new path from the database.. - document = new Document(documentId); - - document.Publish(new umbraco.BusinessLogic.User(0)); - //using library.publish to support load balancing. - //umbraco.library.PublishSingleNode(d.Id); - umbraco.library.UpdateDocumentCache(document.Id); - - //PPH added handling of load balanced moving of multiple nodes... - if (document.HasChildren) - handleChildNodes(document); - - //Using the general Refresh content method instead as it supports load balancing. - //we only need to do this if the node is actually published. - library.RefreshContent(); - } - - document.Save(); //stub to save stuff to the db. + library.RefreshContent(); } else { diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/editContent.aspx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/editContent.aspx.cs index 0fc4268239..08fa0f6ed8 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/editContent.aspx.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/editContent.aspx.cs @@ -331,8 +331,15 @@ namespace umbraco.cms.presentation _documentHasPublishedVersion = _document.HasPublishedVersion(); var descendants = ApplicationContext.Current.Services.ContentService.GetDescendants(_document.Id); - foreach (var descendant in descendants.Where(descendant => descendant.HasPublishedVersion())) - library.UpdateDocumentCache(descendant.Id); + var publishableDescendants = descendants.Where(descendant => descendant.HasPublishedVersion()).ToList(); + if(publishableDescendants.Any()) + { + foreach (var descendant in publishableDescendants) + { + library.UpdateDocumentCache(descendant.Id); + } + library.RefreshContent(); + } } else {